java線程池原理
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
76套java從入門到精通實(shí)戰(zhàn)課程分享
為什么使用線程池?
1.降低資源消耗
通過重復(fù)利用創(chuàng)建好的線程,來降低我們創(chuàng)建和銷毀線程的造成資源的消耗。
2.提高響應(yīng)速度
任務(wù)執(zhí)行后,直接通過已經(jīng)創(chuàng)建好的線程執(zhí)行,提高我們的響應(yīng)速度。
3.提高線程的可管理性
線程資源和我們服務(wù)器的cpu資源息息相關(guān),不能任意地?zé)o限制創(chuàng)建,不僅消耗我們系統(tǒng)資源,還會(huì)降低系統(tǒng)的響應(yīng)速度。使用線程池可以統(tǒng)一監(jiān)控、調(diào)度和調(diào)優(yōu)。
線程池分類
Executor框架的最頂層實(shí)現(xiàn)是ThreadPoolExecutor類,Executors工廠類中提供了以下四種:
newScheduledThreadPool:定時(shí)任務(wù)線程池
newSingleThreadScheduledExecutor:只有一個(gè)線程的定時(shí)任務(wù)線程池
newFixedThreadPool:固定線程數(shù)量的線程池
newCachedThreadPool:可緩存的線程池
在實(shí)際項(xiàng)目使用過程中,一般不會(huì)使用自帶的這幾種創(chuàng)建方式,下面會(huì)將解具體原因。
線程池的核心參數(shù)
corePoolSize: 核心池的大小。當(dāng)有任務(wù)來之后,就會(huì)創(chuàng)建一個(gè)線程去執(zhí)行任務(wù),當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會(huì)把到達(dá)的任務(wù)放到緩存隊(duì)列當(dāng)中;
maximumPoolSize: 線程池最大線程數(shù),它表示在線程池中最多能創(chuàng)建多少個(gè)線程;
keepAliveTime: 表示超出corePoolSize的線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會(huì)終止;
unit:參數(shù)keepAliveTime的時(shí)間單位,有7種取值,在TimeUnit類中有7種靜態(tài)屬性;
workQueue: 阻塞隊(duì)列,當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會(huì)把到達(dá)的任務(wù)放到緩存隊(duì)列當(dāng)中,通常初始化時(shí)需要指定隊(duì)列大小;
threadFactory: 創(chuàng)建線程的工廠,指定線程前綴,來識(shí)別不同業(yè)務(wù)所需的線程池,方便問題的排查;
handler:拒絕策略,當(dāng)任務(wù)達(dá)到maximumPoolSize最大線程數(shù)量時(shí),通過指定不同的拒絕策略,來對(duì)當(dāng)前任務(wù)做具體的處理。內(nèi)置了有4種策略:
AbortPolicy:直接拒絕,拋出異常;
CallerRunsPolicy:在主線程中直接執(zhí)行任務(wù)的run方法;
DiscardOldestPolicy:阻塞隊(duì)列中丟棄最老的未處理任務(wù),然后執(zhí)行任務(wù);
DiscardPolicy:靜默丟棄任務(wù)
整個(gè)流程
下圖是線程池主要的4個(gè)流程,結(jié)合了線程池的具體源碼。

線程池源碼分析
new線程池時(shí),初始化線程池參數(shù):
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}調(diào)用線程池的execute():
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//1.小于核心線程池時(shí),創(chuàng)建新的線程
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//2.任務(wù)大于核心線程時(shí),將任務(wù)放到阻塞隊(duì)列中
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//3.大于最大線程時(shí)
else if (!addWorker(command, false))
//4.執(zhí)行拒絕策略
reject(command);
}
Worker分析
將每個(gè)任務(wù)封住為Worker:
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable然后通過while循環(huán)獲取阻塞隊(duì)列中的任務(wù), 調(diào)用task.run()就會(huì)執(zhí)行我們具體的任務(wù)。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
————————————————
版權(quán)聲明:本文為CSDN博主「darmi-大張」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/qq_28175019/article/details/115426872
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點(diǎn)贊支持下哈 
