import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; public class Ch09_Executor { private static void run(ExecutorService threadPool) { for(int i = 1; i < 5; i++) { final int taskID = i; threadPool.execute(new Runnable() { @Override public void run() { for(int i = 1; i < 5; i++) { try { Thread.sleep(20);// 爲了測試出效果,讓每次任務執行都須要必定時間 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("第" + taskID + "次任務的第" + i + "次執行"); } } }); } threadPool.shutdown();// 任務執行完畢,關閉線程池 } public static void main(String[] args) { // 建立能夠容納3個線程的線程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 線程池的大小會根據執行的任務數動態分配 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); // 建立單個線程的線程池,若是當前線程在執行任務時忽然中斷,則會建立一個新的線程替代它繼續執行任務 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 效果相似於Timer定時器 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); run(fixedThreadPool); // run(cachedThreadPool); // run(singleThreadPool); // run(scheduledThreadPool); } }
CachedThreadPool會建立一個緩存區,將初始化的線程緩存起來。會終止而且從緩存中移除已有60秒未被使用的線程。java
若是線程有可用的,就使用以前建立好的線程,緩存
若是線程沒有可用的,就新建立線程。服務器
// 線程池的大小會根據執行的任務數動態分配 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, //core pool size Integer.MAX_VALUE, //maximum pool size 60L, //keep alive time TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
執行結果:併發
第1次任務的第1次執行
第4次任務的第1次執行
第3次任務的第1次執行
第2次任務的第1次執行
第3次任務的第2次執行
第4次任務的第2次執行
第2次任務的第2次執行
第1次任務的第2次執行
第2次任務的第3次執行
第4次任務的第3次執行
第3次任務的第3次執行
第1次任務的第3次執行
第2次任務的第4次執行
第1次任務的第4次執行
第3次任務的第4次執行
第4次任務的第4次執行
4個任務是交替執行的。異步
在FixedThreadPool中,有一個固定大小的池。ide
若是當前須要執行的任務超過池大小,那麼多出的任務處於等待狀態,直到有空閒下來的線程執行任務,源碼分析
若是當前須要執行的任務小於池大小,空閒的線程也不會去銷燬。測試
// 建立能夠容納3個線程的線程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, //core pool size nThreads, //maximum pool size 0L, //keep alive time TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
執行結果:spa
第1次任務的第1次執行
第3次任務的第1次執行
第2次任務的第1次執行
第3次任務的第2次執行
第2次任務的第2次執行
第1次任務的第2次執行
第3次任務的第3次執行
第1次任務的第3次執行
第2次任務的第3次執行
第3次任務的第4次執行
第1次任務的第4次執行
第2次任務的第4次執行
第4次任務的第1次執行
第4次任務的第2次執行
第4次任務的第3次執行
第4次任務的第4次執行
建立了一個固定大小的線程池,容量爲3,而後循環執行了4個任務。由輸出結果能夠看到,前3個任務首先執行完,而後空閒下來的線程去執行第4個任務。線程
SingleThreadExecutor獲得的是一個單個的線程,這個線程會保證你的任務執行完成。
若是當前線程意外終止,會建立一個新線程繼續執行任務,這和咱們直接建立線程不一樣,也和newFixedThreadPool(1)不一樣。
// 建立單個線程的線程池,若是當前線程在執行任務時忽然中斷,則會建立一個新的線程替代它繼續執行任務 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, //core pool size 1, //maximum pool size 0L, //keep alive time TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
執行結果:
第1次任務的第1次執行
第1次任務的第2次執行
第1次任務的第3次執行
第1次任務的第4次執行
第2次任務的第1次執行
第2次任務的第2次執行
第2次任務的第3次執行
第2次任務的第4次執行
第3次任務的第1次執行
第3次任務的第2次執行
第3次任務的第3次執行
第3次任務的第4次執行
第4次任務的第1次執行
第4次任務的第2次執行
第4次任務的第3次執行
第4次任務的第4次執行
4個任務是順序執行的。
ScheduledThreadPool是一個固定大小的線程池,與FixedThreadPool相似,執行的任務是定時執行。
// 效果相似於Timer定時器 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, //core pool size Integer.MAX_VALUE, //maximum pool size 0, //keep alive time TimeUnit.NANOSECONDS, new DelayedWorkQueue()); }
執行結果:
第1次任務的第1次執行
第2次任務的第1次執行
第3次任務的第1次執行
第2次任務的第2次執行
第1次任務的第2次執行
第3次任務的第2次執行
第2次任務的第3次執行
第1次任務的第3次執行
第3次任務的第3次執行
第2次任務的第4次執行
第1次任務的第4次執行
第3次任務的第4次執行
第4次任務的第1次執行
第4次任務的第2次執行
第4次任務的第3次執行
第4次任務的第4次執行
——與FixedThreadPool的區別?