更新時間:2020-11-16 17:32:34 來源:動力節點 瀏覽1763次
我們在工作中或多或少都使用過線程池,但是為什么要使用線程池呢?從他的名字中我們就應該知道,線程池使用了一種池化技術,和很多其他池化技術一樣,都是為了更高效的利用資源,例如鏈接池,內存池等等。那么,線程池的工作原理到底是怎樣的呢?
實際上,線程池是一種生產者 - 消費者模式,線程池的使用方是生產者,線程池本身是消費者。我們可以通過下面的代碼來理解線程池的工作原理。
public class ThreadPoolDemo {
//利用阻塞隊列實現生產者-消費者模式
BlockingQueue
//保存內部工作線程
List
private ThreadPoolDemo(int poolSize, BlockingQueue
this.workQueue = workQueue;
// 創建工作線程
for (int idx = 0; idx < poolSize; idx++) {
WorkerThread work = new WorkerThread();
work.start();
threads.add(work);
}
}
// 提交任務
public void execute(Runnable command) throws InterruptedException {
workQueue.put(command);
}
// 工作線程負責消費任務,并執行任務
class WorkerThread extends Thread {
public void run() {
//循環取任務并執行
while (true) {
Runnable task = null;
try {
task = workQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
assert task != null;
task.run();
}
}
}
public static void main(String[] args) throws InterruptedException {
BlockingQueue
new LinkedBlockingQueue<>(2);
// 創建線程池
ThreadPoolDemo pool = new ThreadPoolDemo(10, workQueue);
// 提交任務
pool.execute(()->{
System.out.println("hello world");
});
}
}
通過上面的Demo可見,線程池的創建都是通過ThreadPoolExecutor完成的,來看一下它的構造方法。
# -> ThreadPoolExecutor構造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
...
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
構造方法聲明的一系列參數非常重要,理解了它們線程池的基本原理你就掌握了,我們來看看他們的具體含義:
corePoolSize 核心線程數,除非設置核心線程超時(allowCoreThreadTimeOut),線程一直存活在線程池中,即使線程處于空閑狀態。
maximumPoolSize 線程池中允許存在的最大線程數。
workQueue 工作隊列,當核心線程都處于繁忙狀態時,將任務提交到工作隊列中。如果工作隊列也超過了容量,會去嘗試創建一個非核心線程執行任務。
keepAliveTime 非核心線程處理空閑狀態的最長時間,超過該值線程則會被回收。
threadFactory 線程工廠類,用于創建線程。
RejectedExecutionHandler 工作隊列飽和策略,比如丟棄、拋出異常等。
線程池創建完成后,可通過execute方法提交任務,線程池根據當前運行狀態和特定參數對任務進處理,整體模型如下圖:
在 ThreadPoolDemo 的內部,維護了一個阻塞隊列 workQueue 和一組工作線程,工作線程的個數由構造函數中的 poolSize 來指定。用戶通過調用 execute() 方法來提交 Runnable 任務,execute() 方法的內部實現僅僅是將任務加入到 workQueue 中。ThreadPoolDemo 內部維護的工作線程會消費 workQueue 中的任務并執行任務,相關的代碼就是代碼中的 while 循環。
以上就是對線程池的工作原理的探究,就整個線程池工作原理而言,其中最重要的還是線程池的飽和策略,用戶通過實現RejectedExecutionHandler接口自定義飽和策略,并通過ThreadPoolExecutor多參的構造函數傳入。也許你看完了本文,對線程池的工作原理理解的還不夠透徹,那么請觀看本站的多線程教程吧,讓你全面掌握多線程相關知識!
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習