1. Java線程池
線程池:顧名思義,用一個池子裝載多個線程,使用池子去管理多個線程。
問題來源:應用大量通過new Thread()方法創建執行時間短的線程,較大的消耗系統資源並且系統的響應速度變慢。【在一個什么程度上能夠判斷啟用線程池對系統的資源消耗比啟動定量的new Thread()資源消耗低?這個怎么測試?】【用戶體驗卡頓?慢?觀察CPU百分比?】
解決辦法:使用線程池管理短時間執行完畢的大量線程,通過重用已存在的線程,降低線程創建和銷毀造成的消耗,提高系統響應速度。
2. Java線程池快速學習教程
2.1 創建線程池

圖1 Executors靜態方法圖
2.2 線程池使用方法

圖2 ExecutorService方法圖
2.3 線程池快速使用舉例
問題:線程池同時接受兩個線程,兩個線程分別執行打印0~100;
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 public class Test { 5 public static void main(String[] args) { 6 ExecutorService pool = Executors.newCachedThreadPool(); 7 pool.submit(new TestThread()); 8 pool.submit(new TestThread()); 9 pool.shutdown(); 10 } 11 12 } 13 14 15 class TestThread implements Runnable{ 16 @Override 17 public void run(){ 18 for(int i = 0; i <= 100; ++i){ 19 System.out.println(Thread.currentThread().getName() + ": " + i); 20 try { 21 Thread.sleep( (long) (1000L * Math.random())); 22 } catch (InterruptedException e) { 23 e.printStackTrace(); 24 } 25 } 26 } 27 }
3. 線程池原理:
3.1 線程池ThreadPoolExecutor
Executors類提供靜態工廠方法,如圖1所示,這些方法最終都是通過ThreadPoolExecutor類來實現。
構造函數如下所示:
1 public ThreadPoolExecutor(int corePoolSize, 2 int maximumPoolSize, 3 long keepAliveTime, 4 TimeUnit unit, 5 BlockingQueue<Runnable> workQueue) { 6 this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, 7 Executors.defaultThreadFactory(), defaultHandler); 8 }
備注:
1、corePoolSize(線程池基本大小) >= 0;【當前最大並行運行線程數】
2、maximumPoolSize(線程池最大大小) >= 1;【當前最大創建線程數】
3、keepAliveTime(線程存活保持時間) >= 0;【線程在線程池空閑時間超過這個時間,會被終止掉】
4、workQueue(任務隊列)不能為空;【用於傳輸和保存等待執行任務的阻塞隊列】
5、handler(線程飽和策略)不能為空。【當線程池和隊列已滿的處理策略】
3.2 Executors類提供靜態工廠方法默認參數
| 工廠方法 |
corePoolSize |
maximumPoolSize |
KeepAliveTime |
workQueue |
| nreCachedThreadPool() |
0 |
Integer.MAX_VALUE |
60L |
SyschronousQueue |
| newFixedThreadPool(int nThreads) |
nThreads |
nThreads |
0 |
LindedBlockingQueue |
| newSingleThreadExecutor() |
1 |
1 |
0 |
LindedBlockingQueue |
| newScheduledThreadPool(int corePoolSize) |
corePoolSize |
Integer.MAX_VALUE |
0 |
DelayedWorkQueue |
| newSingleThreadScheduledExecutor() |
1 |
Integer.MAX_VALUE |
0 |
DelayedWorkQueue |
3.3 線程池添加任務過程
添加線程即提交任務,線程添加到線程池的過程:

圖3 線程添加到線程池過程圖
4. 總結:
1、根據需要生成線程池;
2、類實現Runnable中的run方法;
3、使用execute或submit方法提交任務;
4、線程池全部線程執行完畢並且不再需要線程池時,應用shutdown()關閉資源。
2016.09.17
5. 正式工作三個月后感想:
1、假設你只是想要一個線程執行完一些操作並且沒有任何與其他線程進行通信與阻塞問題,你大概可以用匿名生成new Thread().start()方法來執行。
2、corePoolSize這個參數很重要,當前最大並行運行線程數,就是可以使用newSingleThreadExecutor創建單線程的線程池,將execute執行的任務,一個一個線程順序執行擺脫鎖的問題。
3、shutdown關閉線程池,但是會執行完已提交的任務,shutdownNow關閉線程池並關閉所有任務,切記。
2017.08.06
