完全解析線程池ThreadPool原理&使用
阿新 • • 發佈:2018-04-27
ati maximum adf 斷線 sched 源碼 調用 executor 線程池
目錄
1. 簡介
2. 工作原理
2.1 核心參數
- 線程池中有6個核心參數,具體如下
- 上述6個參數的配置 決定了 線程池的功能,具體設置時機 = 創建 線程池類對象時 傳入
ThreadPoolExecutor
類 = 線程池的真正實現類- 開發者可根據不同需求 配置核心參數,從而實現自定義線程池
// 創建線程池對象如下
// 通過 構造方法 配置核心參數
Executor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
sPoolWorkQueue,
sThreadFactory
);
// 構造函數源碼分析
public ThreadPoolExecutor (int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable workQueue>,
ThreadFactory threadFactory )
1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
註:Java
裏已內置4種常用的線程池(即 已經配置好核心參數),下面會詳細說明
2.2 內部原理邏輯
當線程池運行時,遵循以下工作邏輯
3. 使用流程
線程池的使用流程如下
// 1. 創建線程池
// 創建時,通過配置線程池的參數,從而實現自己所需的線程池
Executor threadPool = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
sPoolWorkQueue,
sThreadFactory
);
// 註:在Java中,已內置4種常見線程池,下面會詳細說明
// 2. 向線程池提交任務:execute()
// 說明:傳入 Runnable對象
threadPool.execute(new Runnable(www.fengshen157.com) {
@Override
public void run(www.micheng178.com ) {
... // 線程執行任務
}
});
// 3. 關閉線程池shutdown()
threadPool.shutdown();
// 關閉線程的原理
// a. 遍歷線程池中的所有工作線程
// b. 逐個調用線程的interrupt()中斷線程(註:無法響應中斷的任務可能永遠無法終止)
// 也可調用shutdownNow()關閉線程:threadPool.shutdownNow()
// 二者區別:
// shutdown:設置 線程池的狀態 為 SHUTDOWN,然後中斷所有沒有正在執行任務的線程
// shutdownNow:設置 線程池的狀態 為 STOP,然後嘗試停止所有的正在執行或暫停任務的線程,並返回等待執行任務的列表
// 使用建議:一般調用shutdown()關閉線程池;若任務不一定要執行完,則調用shutdownNow()
4. 常見的4類功能線程池
根據參數的不同配置,Java
中最常見的線程池有4類:
- 定長線程池(
FixedThreadPool
) - 定時線程池(
ScheduledThreadPool
www.baohuayule.cn ) - 可緩存線程池(
CachedThreadPool
) - 單線程化線程池(
SingleThreadExecutor
)
即 對於上述4類線程池,
Java
已根據 應用場景 配置好核心參數
4.1 定長線程池(FixedThreadPool)
- 特點:只有核心線程 & 不會被回收、線程數量固定、任務隊列無大小限制(超出的線程任務會在隊列中等待)
- 應用場景:控制線程最大並發數
- 具體使用:通過 Executors.newFixedThreadPool() 創建
- 示例:
// 1. 創建定長線程池對象 & 設置線程池線程數量固定為3
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(www.baohuayule.com3);
// 2. 創建好Runnable類線程對象 & 需執行的任務
Runnable task =new Runnable(){
public void run(www.yszx11.cn/){
System.out.println("執行任務啦");
}
};
// 3. 向線程池提交任務:execute()
fixedThreadPool.execute(task);
// 4. 關閉線程池
4.2 定時線程池(ScheduledThreadPool )
- 特點:核心線程數量固定、非核心線程數量無限制(閑置時馬上回收)
- 應用場景:執行定時 / 周期性 任務
- 使用:通過Executors.newScheduledThreadPool()創建
- 示例:
// 1. 創建 定時線程池對象 & 設置線程池線程數量固定為5
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
// 2. 創建好Runnable類線程對象 & 需執行的任務
Runnable task =new Runnable(){
public void run(www.leyouzaixan.cn){
System.out.println("執行任務啦");
}
};
// 3. 向線程池提交任務:schedule()
scheduledThreadPool.schedule(task, 1, TimeUnit.SECONDS); /www.255055.cn/ / 延遲1s後執行任務
scheduledThreadPool.scheduleAtFixedRate(task,10,1000,TimeUnit.MILLISECONDS);// 延遲10ms後、每隔1000ms執行任務
// 4. 關閉線程池
scheduledThreadPool.shutdown();
4.3 可緩存線程池(CachedThreadPool)
- 特點:只有非核心線程、線程數量不固定(可無限大)、靈活回收空閑線程(具備超時機制,全部回收時幾乎不占系統資源)、新建線程(無線程可用時)
任何線程任務到來都會立刻執行,不需要等待
- 應用場景:執行大量、耗時少的線程任務
- 使用:通過Executors.newCachedThreadPool()創建
- 示例:
// 1. 創建可緩存線程池對象
ExecutorService cachedThreadPool www.wanmeiyuele.cn = Executors.newCachedThreadPool();
// 2. 創建好Runnable類線程對象 & 需執行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執行任務啦");
}
};
// 3. 向線程池提交任務:execute(www.365soke.cn)
cachedThreadPool.execute(task);
// 4. 關閉線程池
cachedThreadPool.shutdown();
//當執行第二個任務時第一個任務已經完成
4.4 單線程化線程池(SingleThreadExecutor)
-
特點:只有一個核心線程(保證所有任務按照指定順序在一個線程中執行,不需要處理線程同步的問題)
-
應用場景:不適合並發但可能引起IO阻塞性及影響UI線程響應的操作,如數據庫操作,文件操作等
- 使用:通過Executors.newSingleThreadExecutor()創建
- 示例:
// 1. 創建單線程化線程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// 2. 創建好Runnable類線程對象 & 需執行的任務
Runnable task =new Runnable(){
public void run(){
System.out.println("執行任務啦");
}
};
// 3. 向線程池提交任務:execute()
singleThreadExecutor.execute(task);
// 4. 關閉線程池
singleThreadExecutor.shutdown();
4.5 常見線程池 總結 & 對比
5. 總結
完全解析線程池ThreadPool原理&使用