更新時間:2020-11-16 17:32:34 來源:動力節(jié)點(diǎn) 瀏覽2085次
我們在工作中或多或少都使用過線程池,但是為什么要使用線程池呢?從他的名字中我們就應(yīng)該知道,線程池使用了一種池化技術(shù),和很多其他池化技術(shù)一樣,都是為了更高效的利用資源,例如鏈接池,內(nèi)存池等等。那么,線程池的工作原理到底是怎樣的呢?
實際上,線程池是一種生產(chǎn)者 - 消費(fèi)者模式,線程池的使用方是生產(chǎn)者,線程池本身是消費(fèi)者。我們可以通過下面的代碼來理解線程池的工作原理。
public class ThreadPoolDemo {
//利用阻塞隊列實現(xiàn)生產(chǎn)者-消費(fèi)者模式
BlockingQueue
//保存內(nèi)部工作線程
List
private ThreadPoolDemo(int poolSize, BlockingQueue
this.workQueue = workQueue;
// 創(chuàng)建工作線程
for (int idx = 0; idx < poolSize; idx++) {
WorkerThread work = new WorkerThread();
work.start();
threads.add(work);
}
}
// 提交任務(wù)
public void execute(Runnable command) throws InterruptedException {
workQueue.put(command);
}
// 工作線程負(fù)責(zé)消費(fèi)任務(wù),并執(zhí)行任務(wù)
class WorkerThread extends Thread {
public void run() {
//循環(huán)取任務(wù)并執(zhí)行
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);
// 創(chuàng)建線程池
ThreadPoolDemo pool = new ThreadPoolDemo(10, workQueue);
// 提交任務(wù)
pool.execute(()->{
System.out.println("hello world");
});
}
}
通過上面的Demo可見,線程池的創(chuàng)建都是通過ThreadPoolExecutor完成的,來看一下它的構(gòu)造方法。
# -> ThreadPoolExecutor構(gòu)造方法
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;
}
構(gòu)造方法聲明的一系列參數(shù)非常重要,理解了它們線程池的基本原理你就掌握了,我們來看看他們的具體含義:
corePoolSize 核心線程數(shù),除非設(shè)置核心線程超時(allowCoreThreadTimeOut),線程一直存活在線程池中,即使線程處于空閑狀態(tài)。
maximumPoolSize 線程池中允許存在的最大線程數(shù)。
workQueue 工作隊列,當(dāng)核心線程都處于繁忙狀態(tài)時,將任務(wù)提交到工作隊列中。如果工作隊列也超過了容量,會去嘗試創(chuàng)建一個非核心線程執(zhí)行任務(wù)。
keepAliveTime 非核心線程處理空閑狀態(tài)的最長時間,超過該值線程則會被回收。
threadFactory 線程工廠類,用于創(chuàng)建線程。
RejectedExecutionHandler 工作隊列飽和策略,比如丟棄、拋出異常等。
線程池創(chuàng)建完成后,可通過execute方法提交任務(wù),線程池根據(jù)當(dāng)前運(yùn)行狀態(tài)和特定參數(shù)對任務(wù)進(jìn)處理,整體模型如下圖:

在 ThreadPoolDemo 的內(nèi)部,維護(hù)了一個阻塞隊列 workQueue 和一組工作線程,工作線程的個數(shù)由構(gòu)造函數(shù)中的 poolSize 來指定。用戶通過調(diào)用 execute() 方法來提交 Runnable 任務(wù),execute() 方法的內(nèi)部實現(xiàn)僅僅是將任務(wù)加入到 workQueue 中。ThreadPoolDemo 內(nèi)部維護(hù)的工作線程會消費(fèi) workQueue 中的任務(wù)并執(zhí)行任務(wù),相關(guān)的代碼就是代碼中的 while 循環(huán)。
以上就是對線程池的工作原理的探究,就整個線程池工作原理而言,其中最重要的還是線程池的飽和策略,用戶通過實現(xiàn)RejectedExecutionHandler接口自定義飽和策略,并通過ThreadPoolExecutor多參的構(gòu)造函數(shù)傳入。也許你看完了本文,對線程池的工作原理理解的還不夠透徹,那么請觀看本站的多線程教程吧,讓你全面掌握多線程相關(guān)知識!

初級 202925

初級 203221

初級 202629

初級 203743