簡(jiǎn)介
整理一些面試時(shí)線程池常問的問題
1.核心線程如何一直?;?/h3>
第一問.png

答案:由于任務(wù)都是存在阻塞隊(duì)列中,Worker從隊(duì)列拿任務(wù)時(shí)通過阻塞隊(duì)列take()方法讓線程等待,使得Worker的run()方法一直阻塞,直到獲取到執(zhí)行任務(wù),執(zhí)行完任務(wù)后繼續(xù)阻塞等待,使得線程生命周期一直在RUNNABLE和WAITING狀態(tài)之間流轉(zhuǎn),保證核心線程一直存活。
2.非核心線程何時(shí)死亡?
還是剛才的代碼:

答案:非核心線程延遲死亡的條件為當(dāng)前線程數(shù)大于最大核心線程數(shù),并且也獲取不到任務(wù)。
3.核心線程何時(shí)死亡?
還是剛才的代碼:

allowCoreThreadTimeOut是ThreadPoolExecutor類的成員屬性,只要設(shè)置這個(gè)變量,在執(zhí)行keepAliveTime還未獲取到執(zhí)行任務(wù)時(shí)就會(huì)移出線程池。
4.線程池如何保證并發(fā)安全
ThreadPoolExecutor中使用HashSet用于存放Worker,當(dāng)添加一個(gè)線程時(shí):

對(duì)于workers集合的操作都是采用ReentrantLock鎖來保證的,同一時(shí)間只有一個(gè)線程可以操作集合對(duì)象
5.線程數(shù)設(shè)置多少合適
對(duì)于 CPU 密集型計(jì)算,多線程本質(zhì)上是提升多核 CPU 的利用率,所以對(duì)于一個(gè) 4 核的 CPU,每個(gè)核一個(gè)線程,理論上創(chuàng)建 4 個(gè)線程就可以了,再多創(chuàng)建線程也只是增加線程切換的成本。所以,對(duì)于 CPU 密集型的計(jì)算場(chǎng)景,理論上“線程的數(shù)量 =CPU 核數(shù)”就是最合適的。不過在工程上,線程的數(shù)量一般會(huì)設(shè)置為“CPU 核數(shù) +1”,這樣的話,當(dāng)線程因?yàn)榕紶柕膬?nèi)存頁失效或其他原因?qū)е伦枞麜r(shí),這個(gè)額外的線程可以頂上,從而保證 CPU 的利用率;
對(duì)于 I/O 密集型的計(jì)算場(chǎng)景,如果 CPU 計(jì)算和 I/O 操作的耗時(shí)是1:1,那么 2 個(gè)線程是最合適的。如果 CPU 計(jì)算和 I/O 操作的耗時(shí)是 1:2,那多少個(gè)線程合適呢?是 3 個(gè)線程。
例如:CPU 在 A、B、C 三個(gè)線程之間切換,對(duì)于線程 A,當(dāng) CPU 從B、C 切換回來時(shí),線程 A 正好執(zhí)行完 I/O 操作。這樣 CPU 和 I/O 設(shè)備的利用率都達(dá)到了100%;