線程池中阻塞隊列的作用?為什么是先添加隊列而不是先創建最大線程?
1 一般的隊列只能保證作為一個有限長度的緩沖區,如果超出了緩沖長度,就無法保留當前的任務了,阻塞隊列通過阻塞可以保留住當前想要繼續入隊的任務。
阻塞隊列可以保證任務隊列中沒有任務時阻塞獲取任務的線程,使得線程進入wait狀態,釋放cpu資源。
阻塞隊列自帶阻塞和喚醒功能,不需要做額外處理,無任務執行時,線程池利用阻塞隊列的take方法掛起,從而維持核心線程的存活,不至於一直占用CPU資源。
2 在創建新線程的時候,是要獲取全局鎖的,這個時候其他的就需要阻塞,影響了整體效率。
就好比一個企業里面有十個(core)正式工的名額,最多招十個正式工(核心線程),要是任務超過正式人數(task>core)的情況下,工廠領導(線程池)不是首先擴招工人,還是這十個人,但是任務可以稍積壓一下。即先放到
隊列中去(代價低)。十個正式工慢慢干,遲早會干完的,如果任務還在持續增加,超過正式工的加班忍耐極限了(隊列滿了),就招外包(非核心線程)幫忙了,還是正式工加外包還不能完成任務,那么新來的任務就會被領導拒絕(線程池拒絕策略)。
線程池中線程復用的原理
線程池將線程和任務進行解耦,線程是線程,任務時任務,擺脫了之前Thread創建線程時一個線程必須對應一個任務的限制。
在線程池中,同一個線程可以從阻塞隊列中不斷的獲取新任務執行,其核心原理在於線程池對Thread進行了封裝,並不是每一次調用線程都會調用Thread.start()來創建新線程,而是讓每個線程去執行循環任務,在這個循環任務中不停檢查是否有任務需要被執行,
如果有,直接執行,也就是調用任務中的run方法,將run方法當成一個普通方法執行,通過這種方式只使固定的線程就將所有任務run方法串聯起來了。