如何設(shè)置線程池參數(shù)
假設(shè):
每秒任務(wù)數(shù) tasks per second.? tasks = 1000 t / s
最大每秒任務(wù)數(shù) max tasks per second maxTasks = 3000 t / s
每個(gè)任務(wù)花費(fèi)時(shí)間 task cost time costTime? = 0.1s
系統(tǒng)容許最大響應(yīng)時(shí)間 max response time maxTime = 2s
corePoolSize = tasks / (1 / costTime) = 1000 * 0.1 = 100
queueCapacity = corePoolSize / costTime * maxTime = 100 / 0.1 * 2 = 2000
maxPoolSize = (maxTasks -?queueCapacity) /?(1 / costTime) = (3000 - 2000) * 10 = 10000
線程池中為什么要使用阻塞隊(duì)列?
如果新任務(wù)的到達(dá)速率超過了線程池的處理速率,那么新到來的請(qǐng)求將累加起來,這樣的話將耗盡資源。
線程池創(chuàng)建線程需要獲取mainlock這個(gè)全局鎖,影響并發(fā)效率,阻塞隊(duì)列可以很好的緩沖。
corePoolSize設(shè)置為0會(huì)怎么樣?
如果添加隊(duì)列成功,判斷當(dāng)前池內(nèi)線程數(shù)是否為0,如果是則創(chuàng)建一個(gè)firstTask為null的worker,這個(gè)worker會(huì)從等待隊(duì)列中獲取任務(wù)并執(zhí)行。
如果添加到等待隊(duì)列失敗,一般是隊(duì)列已滿,才會(huì)再嘗試創(chuàng)建新的線程。
線程池創(chuàng)建之后,會(huì)立即創(chuàng)建核心線程么?
在剛剛創(chuàng)建ThreadPoolExecutor的時(shí)候,線程并不會(huì)立即啟動(dòng),而是要等到有任務(wù)提交時(shí)才會(huì)啟動(dòng),除非調(diào)用了prestartCoreThread/prestartAllCoreThreads事先啟動(dòng)核心線程。
核心線程永遠(yuǎn)不會(huì)銷毀么?
從JDK1.6開始,提供了方法allowsCoreThreadTimeOut,如果傳參為true,則允許閑置的核心線程被終止。
空閑線程過多會(huì)有什么問題?
會(huì)占用內(nèi)存
-虛擬機(jī)棧
-本地方法棧
-程序計(jì)數(shù)器
-ThreadLocal
-局部變量
-TLAB
shutdown和shutdownNow的區(qū)別
shutdown => 平緩關(guān)閉,等待所有已添加到線程池中的任務(wù)執(zhí)行完再關(guān)閉。
shutdownNow => 立刻關(guān)閉,停止正在執(zhí)行的任務(wù),并返回隊(duì)列中未執(zhí)行的任務(wù)。
一個(gè)線程池中的線程異常了,那么線程池會(huì)怎么處理這個(gè)線程?
-當(dāng)執(zhí)行方式是execute時(shí),可以看到堆棧異常的輸出。也可以通過setUncaughtExceptionHandler指定處理異常。
-當(dāng)執(zhí)行方式是submit時(shí),堆棧異常沒有輸出。但是調(diào)用Future.get()方法時(shí),可以捕獲到異常。
-不會(huì)影響線程池里面其他線程的正常執(zhí)行。
-線程池會(huì)把這個(gè)線程移除掉,并創(chuàng)建一個(gè)新的線程放到線程池中。