JDK5.0 特性-线程任务执行架构 ScheduledExecutorService

来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291469.html

  1 import java.util.concurrent.Callable;
  2 
  3 import java.util.concurrent.ExecutionException;
  4 
  5 import java.util.concurrent.ExecutorService;
  6 
  7 import java.util.concurrent.Executors;
  8 
  9 import java.util.concurrent.Future;
 10 
 11 import java.util.concurrent.ScheduledExecutorService;
 12 
 13 import java.util.concurrent.TimeUnit;
 14 
 15  
 16 
 17 /**
 18 
 19     在J2SE之前启动一个任务是通过调用Thread类的start方法来实现的,任务的提交和执行是同时进行的,如果想对任务的执行进行调度,或是控制同时执行的线程数量就需要额外的编写代码来完成.
 20 
 21     J2SE5.0提供了一个新的任务执行架构,可以轻松地高度和控制任务的执行,并且可以建立一个线程池来执行任务.
 22 
 23     实例介绍如何使用新的任务执行架构,运行Runnable和Callable任务,包括定时执行任务,按规律执行任务和停止任务.
 24 
 25 关键技术剖析:
 26 
 27     使用新的任务执行框架的关键技术如下:
 28 
 29     1.Executor服务对象是用来执行Runnable任务的,常用的方法如下:
 30 
 31       execute方法用于执行Runnable类型的任务.
 32 
 33     2.ExecutorService服务对象能执行和终止Callable任务,它继承了Executor,所以也能执行Runnable任务.常用的方法如下
 34 
 35       a) submit方法用来提交Callable或Runnable任务,并返回代表此任务的Future对象.
 36 
 37       b) invokeAll方法批处理任务集合,并返回一个代表这些任务的Future对象集合
 38 
 39       c) shutdown方法在完成自己已提交的任务后关闭服务,不再接受新任务.
 40 
 41       d) shutdownNow方法停止所有正在执行的任务并关闭服务.
 42 
 43       e) isTerminated测试是否所有任务都执行完毕了
 44 
 45       g) isShutdown测试是否该ExecutorService已被关闭
 46 
 47     3.ScheduledExecutorService服务对象继承ExecutorService,提供了按时间安排执行任务的功能.常用的方法如下:
 48 
 49       a)schedule(task,initDelay)方法安排所提交的Callable或Runnable任务在initDelay指定的时间后执行.
 50 
 51       b)scheduleAtFixedRate方法安排所提交的Runnable任务按指定的间隔重复执行.
 52 
 53       c)scheduleWithFixedDelay方法安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行.
 54 
 55     4.Executors类用来创建各种服务对象,常用的方法如下:
 56 
 57       a)callable(Runnable task)方法将Runnable的任务转化成Callable的任务.
 58 
 59       b)newSingleThreadExecutor方法产生一个ExecutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用.
 60 
 61       c)newCachedThreadPool方法会产生一个ExecutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用.
 62 
 63       d)newFixedThreadPool(int poolSize)方法产生一个ExecutorService对象,这个对象带有一个大小为poolSize的线程池,若任务数量大于poolSize,任务会被放在一个队列里顺序执行.
 64 
 65       e)newSingleThreadScheduledExecutor方法产生一个ScheduledExecutorService对象,这个对象的线程池大小为1,若任务多于一个,任务将按先后顺序执行.
 66 
 67       f)newScheduledThreadPool(int poolSize)方法产生一个ScheduledExecutorService对象,这个对象的线程池大小为poolSize,若任务数量大于poolSize,任务会在一个队列里等待执行.
 68 
 69 */
 70 
 71 public class ExecuteArch {
 72 
 73        /**该线程输出一行字符串*/
 74 
 75        public static class MyThread implements Runnable{
 76 
 77               public void run(){
 78 
 79                      System.out.println("Task repeating. " + System.currentTimeMillis());
 80 
 81                      try{
 82 
 83                             Thread.sleep(1000);
 84 
 85                      }catch(InterruptedException e){
 86 
 87                             System.out.println("Task interrupted. " + System.currentTimeMillis());
 88 
 89                      }
 90 
 91               }
 92 
 93        }
 94 
 95        /**该Callable结束另一个任务*/
 96 
 97        public static class MyCallable implements Callable{
 98 
 99               private Future future;
100 
101               public MyCallable(Future future){
102 
103                      this.future = future;
104 
105               }
106 
107               public String call(){
108 
109                      System.out.println("To cancell Task..." + System.currentTimeMillis());
110 
111                      this.future.cancel(true);
112 
113                      return "Task cancelled!";
114 
115               }
116 
117        }
118 
119       
120 
121        public static void main(String... args)throwsInterruptedException,ExecutionException{
122 
123               //产生一个ExcutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整
124 
125               //线程执行完任务后返回线程池,供执行下一次任务使用
126 
127               ExecutorService cachedService = Executors.newCachedThreadPool();
128 
129               Future myThreadFuture = cachedService.submit(new MyThread());
130 
131               Future myCallableFuture = cachedService.submit(newMyCallable(myThreadFuture));
132 
133               System.out.println(myCallableFuture.get());
134 
135               System.out.println("--------------------");
136 
137              
138 
139               //将Runnable任务转换成 Callable任务
140 
141               Callable myThreadCallable = Executors.callable(new MyThread());
142 
143               Future myThreadCallableFuture = cachedService.submit(myThreadCallable);
144 
145               //对于Runnable任务,转换成Callable任务后,也没有返回值
146 
147               System.out.println(myThreadCallableFuture.get());
148 
149               cachedService.shutdownNow();
150 
151               System.out.println("--------------------");
152 
153              
154 
155               //产生一个ExecutorService对象,这个对象带有一个大小为poolSize的线程池
156 
157               //若任务大于poolSize,任务会被放在一个queue里顺序执行
158 
159               ExecutorService fixedService = Executors.newFixedThreadPool(2);
160 
161               fixedService.submit(new MyThread());
162 
163               fixedService.submit(new MyThread());
164 
165               //由于线程池大小为2,所以后面的任务必须等待前面的任务执行完毕后才能被执行
166 
167               myThreadFuture = fixedService.submit(new MyThread());
168 
169               myThreadFuture = fixedService.submit(new MyCallable(myThreadFuture));
170 
171               System.out.println(myCallableFuture.get());
172 
173               fixedService.shutdown();
174 
175               System.out.println("--------------------");
176 
177              
178 
179               //产生一个ScheduleExecutorService对象,这个对象的线程池大小为poolSize
180 
181               //若任务数量大于poolSize,任务会在一个queue里等待执行
182 
183               ScheduledExecutorService fixedScheduledService = Executors.newScheduledThreadPool(2);
184 
185               MyThread task1 = new MyThread();
186 
187               //使用任务执行服务立即执行任务1,而且此后每隔2秒执行一次任务1
188 
189               myThreadFuture = fixedScheduledService.scheduleAtFixedRate(task1, 0, 2, TimeUnit.SECONDS);
190 
191               MyCallable task2 = new MyCallable(myThreadFuture);
192 
193               //使用任务执行服务等待5秒后执行任务2,执行它后将任务1关闭.
194 
195               myCallableFuture = fixedScheduledService.schedule(task2,5,TimeUnit.SECONDS);
196 
197               System.out.println(myCallableFuture.get());
198 
199               fixedScheduledService.shutdownNow();            
200 
201        }
202 
203 }