import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
在J2SE之前啟動一個任務是通過調用Thread類的start方法來實作的,任務的送出和執行是同時進行的,如果想對任務的執行進行排程,或是控制同時執行的線程數量就需要額外的編寫代碼來完成.
J2SE5.0提供了一個新的任務執行架構,可以輕松地高度和控制任務的執行,并且可以建立一個線程池來執行任務.
執行個體介紹如何使用新的任務執行架構,運作Runnable和Callable任務,包括定時執行任務,按規律執行任務和停止任務.
關鍵技術剖析:
使用新的任務執行架構的關鍵技術如下:
1.Executor服務對象是用來執行Runnable任務的,常用的方法如下:
execute方法用于執行Runnable類型的任務.
2.ExecutorService服務對象能執行和終止Callable任務,它繼承了Executor,是以也能執行Runnable任務.常用的方法如下
a) submit方法用來送出Callable或Runnable任務,并傳回代表此任務的Future對象.
b) invokeAll方法批處理任務集合,并傳回一個代表這些任務的Future對象集合
c) shutdown方法在完成自己已送出的任務後關閉服務,不再接受新任務.
d) shutdownNow方法停止所有正在執行的任務并關閉服務.
e) isTerminated測試是否所有任務都執行完畢了
g) isShutdown測試是否該ExecutorService已被關閉
3.ScheduledExecutorService服務對象繼承ExecutorService,提供了按時間安排執行任務的功能.常用的方法如下:
a)schedule(task,initDelay)方法安排所送出的Callable或Runnable任務在initDelay指定的時間後執行.
b)scheduleAtFixedRate方法安排所送出的Runnable任務按指定的間隔重複執行.
c)scheduleWithFixedDelay方法安排所送出的Runnable任務在每次執行完後,等待delay所指定的時間後重複執行.
4.Executors類用來建立各種服務對象,常用的方法如下:
a)callable(Runnable task)方法将Runnable的任務轉化成Callable的任務.
b)newSingleThreadExecutor方法産生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務後傳回線程池,供執行下一次任務使用.
c)newCachedThreadPool方法會産生一個ExecutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整,線程執行完任務後傳回線程池,供執行下一次任務使用.
d)newFixedThreadPool(int poolSize)方法産生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池,若任務數量大于poolSize,任務會被放在一個隊列裡順序執行.
e)newSingleThreadScheduledExecutor方法産生一個ScheduledExecutorService對象,這個對象的線程池大小為1,若任務多于一個,任務将按先後順序執行.
f)newScheduledThreadPool(int poolSize)方法産生一個ScheduledExecutorService對象,這個對象的線程池大小為poolSize,若任務數量大于poolSize,任務會在一個隊列裡等待執行.
*/
public class ExecuteArch {
/**該線程輸出一行字元串*/
public static class MyThread implements Runnable{
public void run(){
System.out.println("Task repeating. " + System.currentTimeMillis());
try{
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("Task interrupted. " + System.currentTimeMillis());
}
}
}
/**該Callable結束另一個任務*/
public static class MyCallable implements Callable{
private Future future;
public MyCallable(Future future){
this.future = future;
public String call(){
System.out.println("To cancell Task..." + System.currentTimeMillis());
this.future.cancel(true);
return "Task cancelled!";
public static void main(String... args)throwsInterruptedException,ExecutionException{
//産生一個ExcutorService對象,這個對象帶有一個線程池,線程池的大小會根據需要調整
//線程執行完任務後傳回線程池,供執行下一次任務使用
ExecutorService cachedService = Executors.newCachedThreadPool();
Future myThreadFuture = cachedService.submit(new MyThread());
Future myCallableFuture = cachedService.submit(newMyCallable(myThreadFuture));
System.out.println(myCallableFuture.get());
System.out.println("--------------------");
//将Runnable任務轉換成 Callable任務
Callable myThreadCallable = Executors.callable(new MyThread());
Future myThreadCallableFuture = cachedService.submit(myThreadCallable);
//對于Runnable任務,轉換成Callable任務後,也沒有傳回值
System.out.println(myThreadCallableFuture.get());
cachedService.shutdownNow();
//産生一個ExecutorService對象,這個對象帶有一個大小為poolSize的線程池
//若任務大于poolSize,任務會被放在一個queue裡順序執行
ExecutorService fixedService = Executors.newFixedThreadPool(2);
fixedService.submit(new MyThread());
//由于線程池大小為2,是以後面的任務必須等待前面的任務執行完畢後才能被執行
myThreadFuture = fixedService.submit(new MyThread());
myThreadFuture = fixedService.submit(new MyCallable(myThreadFuture));
fixedService.shutdown();
//産生一個ScheduleExecutorService對象,這個對象的線程池大小為poolSize
//若任務數量大于poolSize,任務會在一個queue裡等待執行
ScheduledExecutorService fixedScheduledService = Executors.newScheduledThreadPool(2);
MyThread task1 = new MyThread();
//使用任務執行服務立即執行任務1,而且此後每隔2秒執行一次任務1
myThreadFuture = fixedScheduledService.scheduleAtFixedRate(task1, 0, 2, TimeUnit.SECONDS);
MyCallable task2 = new MyCallable(myThreadFuture);
//使用任務執行服務等待5秒後執行任務2,執行它後将任務1關閉.
myCallableFuture = fixedScheduledService.schedule(task2,5,TimeUnit.SECONDS);
fixedScheduledService.shutdownNow();
}