java線程池中線程數(shù)量到底是幾
線程池配置
線程池配置,假設(shè)是:
1.最小數(shù)量是5
2.阻塞隊(duì)列容量是10
3.最大數(shù)量是20
線程池里的業(yè)務(wù)線程數(shù)量小于最小數(shù)量(5)
第一個(gè)請(qǐng)求
第一個(gè)請(qǐng)求進(jìn)來的時(shí)候,這個(gè)時(shí)候,線程池沒有線程,就創(chuàng)建新的工作線程(即Worker線程)。
然后,這個(gè)工作線程去處理當(dāng)前請(qǐng)求的業(yè)務(wù)線程。
第二個(gè)請(qǐng)求
第二個(gè)請(qǐng)求進(jìn)來的時(shí)候,這個(gè)時(shí)候,線程池已經(jīng)有了一個(gè)工作線程。
但是,要注意,這個(gè)時(shí)候是不會(huì)復(fù)用線程池里已有的工作線程的。而是創(chuàng)建新的工作線程。
因?yàn)椋€程池里根本沒有復(fù)用線程的概念。
說白了,無(wú)論線程池里已有的這個(gè)工作線程是否在處理業(yè)務(wù)線程,即不管它空閑與否,其實(shí)都會(huì)創(chuàng)建新的工作線程。
第三個(gè)請(qǐng)求
同上,仍然創(chuàng)建新的工作線程。
。。。
第五個(gè)請(qǐng)求
同上。仍然創(chuàng)建新的工作線程。
注意,現(xiàn)在,線程池有幾個(gè)工作線程?5個(gè)。
即,每個(gè)請(qǐng)求進(jìn)來,都創(chuàng)建一個(gè)新的工作線程。
小于阻塞隊(duì)列容量(10)
第六個(gè)請(qǐng)求
第六個(gè)請(qǐng)求進(jìn)來的時(shí)候,提交到阻塞隊(duì)列。
然后,再慢慢消費(fèi)。
具體來說,是由線程池里的工作線程來慢慢消費(fèi)。
具體消費(fèi)的源碼,參考:復(fù)用線程小節(jié)。
第七個(gè)請(qǐng)求
同上,也是先添加到阻塞隊(duì)列。
。。。
第15個(gè)請(qǐng)求
同上,也是先添加到阻塞隊(duì)列。
小于最大數(shù)量(20)
第16個(gè)請(qǐng)求
先來看,正常情況下,阻塞隊(duì)列還沒塞滿(生產(chǎn)環(huán)境的容量一般是1000),就會(huì)被快速處理掉。
然后,當(dāng)新的請(qǐng)求進(jìn)來的時(shí)候,繼續(xù)丟到阻塞隊(duì)列里面去。
這個(gè)是和上面講的一樣。
但是,我們?yōu)榱朔奖憷斫?,現(xiàn)在假設(shè)之前的15個(gè)請(qǐng)求是同時(shí)到達(dá),即
- 前面5個(gè)請(qǐng)求
創(chuàng)建5個(gè)新的請(qǐng)求。
- 后面10個(gè)請(qǐng)求
全部丟到阻塞隊(duì)列。
這個(gè)時(shí)候,阻塞隊(duì)列已經(jīng)滿了。接著,第16個(gè)請(qǐng)求進(jìn)來了,怎么辦?
繼續(xù)創(chuàng)建新的工作線程。
。。。
第35個(gè)請(qǐng)求
同上,繼續(xù)創(chuàng)建新的工作線程。
注意,這個(gè)時(shí)候,線程池里的工作線程的數(shù)量是多少?20。
因?yàn)?/p>
- 前面5個(gè)請(qǐng)求,創(chuàng)建了5個(gè)新的工作線程。
- 最后面的15個(gè)請(qǐng)求(第16到第35),創(chuàng)建了15個(gè)新的工作線程。
所以,總共,創(chuàng)建了20個(gè)新的工作線程。線程池,總共有20個(gè)工作線程。
拒絕策略
第36個(gè)請(qǐng)求
假設(shè)前面的請(qǐng)求都沒有處理完,這個(gè)時(shí)候,來了第36個(gè)請(qǐng)求,怎么辦?
只能采取拒絕策略。
具體采用哪個(gè)拒絕策略?比如說,一般情況下,都是采用丟棄。
復(fù)用線程
前面說了,線程池里沒有復(fù)用線程的概念。
那到底是怎么回事呢?既然不能復(fù)用線程,那搞個(gè)線程池有個(gè)幾把用?
具體是這樣子,雖然,線程池里的工作線程不能被復(fù)用,僅僅是指類似數(shù)據(jù)庫(kù)連接池里的連接的那種復(fù)用,即
- 用的時(shí)候,從連接池取
- 用完了,歸還到連接池
線程池里的對(duì)象復(fù)用,是基于循環(huán),而不是用完之后再還回去。
什么意思呢?就是工作線程,不斷的從阻塞隊(duì)列里取業(yè)務(wù)線程,然后執(zhí)行業(yè)務(wù)線程。
偽代碼
工作線程{ run(){ while(){ 1.從阻塞隊(duì)列,取業(yè)務(wù)線程 2.執(zhí)行業(yè)務(wù)線程; } } }
所以,線程池和連接池的區(qū)別在于,線程池的對(duì)象是線程,可以不斷的循環(huán)讀業(yè)務(wù)線程。而連接池的對(duì)象,是用完了歸還到連接池里去。
jdk源碼-java.util.concurrent.ThreadPoolExecutor#runWorker
/** * 核心步驟 * 1.從阻塞隊(duì)列,讀業(yè)務(wù)線程 * 2.執(zhí)行業(yè)務(wù)線程 * * --- * Main worker run loop. Repeatedly gets tasks from queue and * executes them, while coping with a number of issues: * * 1. We may start out with an initial task, in which case we * don't need to get the first one. Otherwise, as long as pool is * running, we get tasks from getTask. If it returns null then the * worker exits due to changed pool state or configuration * parameters. Other exits result from exception throws in * external code, in which case completedAbruptly holds, which * usually leads processWorkerExit to replace this thread. * * 2. Before running any task, the lock is acquired to prevent * other pool interrupts while the task is executing, and then we * ensure that unless pool is stopping, this thread does not have * its interrupt set. * * 3. Each task run is preceded by a call to beforeExecute, which * might throw an exception, in which case we cause thread to die * (breaking loop with completedAbruptly true) without processing * the task. * * 4. Assuming beforeExecute completes normally, we run the task, * gathering any of its thrown exceptions to send to afterExecute. * We separately handle RuntimeException, Error (both of which the * specs guarantee that we trap) and arbitrary Throwables. * Because we cannot rethrow Throwables within Runnable.run, we * wrap them within Errors on the way out (to the thread's * UncaughtExceptionHandler). Any thrown exception also * conservatively causes thread to die. * * 5. After task.run completes, we call afterExecute, which may * also throw an exception, which will also cause thread to * die. According to JLS Sec 14.20, this exception is the one that * will be in effect even if task.run throws. * * The net effect of the exception mechanics is that afterExecute * and the thread's UncaughtExceptionHandler have as accurate * information as we can provide about any problems encountered by * user code. * * @param w the worker */ final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { //從阻塞隊(duì)列里獲取業(yè)務(wù)線程 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 { //執(zhí)行業(yè)務(wù)線程 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); } }
到此這篇關(guān)于java線程池中線程數(shù)量到底是幾的文章就介紹到這了,更多相關(guān)java 線程數(shù)量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springcloud整合gateway實(shí)現(xiàn)網(wǎng)關(guān)全局過濾器功能
本文主要介紹了springcloud整合gateway實(shí)現(xiàn)網(wǎng)關(guān)全局過濾器功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02Java對(duì)時(shí)間的簡(jiǎn)單操作實(shí)例
這篇文章主要介紹了Java對(duì)時(shí)間的簡(jiǎn)單操作,實(shí)例分析了針對(duì)java.util.Date的各類常見操作,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01java獲取ip地址與網(wǎng)絡(luò)接口的方法示例
這篇文章主要給大家介紹了關(guān)于利用java如何獲取ip地址與網(wǎng)絡(luò)接口的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01SpringBoot+Dubbo+Zookeeper實(shí)現(xiàn)簡(jiǎn)單分布式開發(fā)的應(yīng)用詳解
這篇文章主要介紹了SpringBoot+Dubbo+Zookeeper實(shí)現(xiàn)簡(jiǎn)單分布式開發(fā)的應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01spring boot輸入數(shù)據(jù)校驗(yàn)(validation)的實(shí)現(xiàn)過程
web項(xiàng)目中,用戶的輸入總是被假定不安全不正確的,在被處理前需要做校驗(yàn)。本文介紹在spring boot項(xiàng)目中實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的過程,通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-09-09鑒權(quán)認(rèn)證+aop+注解+過濾feign請(qǐng)求的實(shí)例
這篇文章主要介紹了鑒權(quán)認(rèn)證+aop+注解+過濾feign請(qǐng)求的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03