Java SE5的java.util.concurrent包中的執行器(Executor)將爲你管理Thread對象,從而簡化了併發編程。Executor在客戶端和執行任務之間提供了一個間接層,Executor代替客戶端執行任務。Executor允許你管理異步任務的執行,而無須顯式地管理線程的生命週期。Executor在Java SE5/6中時啓動任務的優選方法。Executor引入了一些功能類來管理和使用線程Thread,其中包括線程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等
接口Executor只有一個方法execute,接口ExecutorService擴展了Executor並添加了一些生命週期管理的方法,如shutdown(可以防止新任務被提交給這個Executor,當前線程將繼續運行在shutdown()被調用之前提交的所有任務)、submit等。一個Executor的生命週期有三種狀態,運行 ,關閉 ,終止。
創建線程池
Executors類,提供了一系列工廠方法用於創先線程池,返回的線程池都實現了ExecutorService接口。
創建固定數目線程的線程池。
public static ExecutorService newFixedThreadPool(int nThreads)
創建一個可緩存的線程池,調用execute 將重用以前構造的線程(如果線程可用)。如果沒有現有線程可用,則創建一個新線程並添加到
池中。終止並從緩存中移除那些已有 60 秒鐘未被使用的線程。
public static ExecutorService newCachedThreadPool()
創建一個單線程化的Executor。以確保任意時刻在任何線程中都只有唯一的任務在運行。其就像是線程數量爲1的FixedThreadPool
public static ExecutorService newSingleThreadExecutor()
創建一個支持定時及週期性的任務執行的線程池,多數情況下可用來替代Timer類。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
Runnable接口和Callable接口
Runnable是執行工作的獨立任務,但是它(方法run())不返回任何值。
而在Java SE5引入的Callabel是一種具有類型參數的泛型,他的類型參數表示的是從方法call()(而不是run())中返回的值,並且必須使用ExcecutorService.submit()方法調用它。
import java.util.*;
import java.util.concurrent.*;
class TaskWithResult implements Callable<String>{
private int id;
public TaskWithResult(int id) {
this.id=id;
}
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "result of TaskWithResult "+id;
}
}
public class CallableDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService exec=
Executors.newCachedThreadPool();
ArrayList<Future<String>> results=
new ArrayList<Future<String>>();
for(int i=0;i<10;i++) {
results.add(exec.submit(new TaskWithResult(i)));
}
for(Future<String> fs:results) {
try {
System.out.println(fs.get());
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
/*
result of TaskWithResult 0
result of TaskWithResult 1
result of TaskWithResult 2
result of TaskWithResult 3
result of TaskWithResult 4
result of TaskWithResult 5
result of TaskWithResult 6
result of TaskWithResult 7
result of TaskWithResult 8
result of TaskWithResult 9
*/
submit()方法會產生future對象,它用Callable返回結果的特定類型進行了參數化。