Java手動配置線程池過程詳解
線程池中,常見有涉及到的:
ExecutorService executorService = Executors.newSingleThreadExecutor();ExecutorService executorService1 = Executors.newCachedThreadPool();ExecutorService executorService2 = Executors.newFixedThreadPool(3);
關(guān)于Executors和ExecutorService從記憶上類似于Collections和List。
但是以上幾種其實不建議使用。最好可以通過自己手動配置ThreadPoolExecutor的形式。
我先創(chuàng)建一個demo:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,5,1L,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy() );
涉及7個參數(shù),按順序分別是
int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler
具體我首先需要結(jié)合參數(shù)解釋下線程池的執(zhí)行原理:
畫了張圖:
如果我用銀行辦理業(yè)務(wù)示例說明如下:
1、首先銀行里面有兩個柜臺,這就是核心線程數(shù)(7大參數(shù)之一)。
2、然后隨著客戶的增加,可能這個兩個柜臺滿了,然后就要請用戶到等候區(qū)里面進(jìn)行等待。這個等候區(qū)就是相當(dāng)于阻塞隊列(七大參數(shù)之一)。
3、然后緊接著客戶越來越多,連阻塞隊列都撐不住了,這個時候,就要請求,上面的領(lǐng)導(dǎo)進(jìn)行多增加柜臺的操作,這個時候,可能加了三個柜臺,現(xiàn)在就有5個柜臺了。這個時候最大的線程數(shù)(七大參數(shù)之一)就是5了。
4、但是這個時候可能客戶又越來越多,這個時候新加的柜臺也受不了,就要開始有拒絕策略了(七大參數(shù)之一)
5、然后過了一段時間,慢慢的,客戶越來越少了,這個時候,發(fā)現(xiàn)漸漸的,柜臺空余出來了。KeepAliveTime(七大參數(shù)之一,加上單位,合計兩個參數(shù))指當(dāng)線程數(shù)大于核心線程數(shù)時,此為終止前多余的空閑線程等待新任務(wù)的最長時間。
6、還有一個參數(shù)是工廠,這個我們不做深入研究,直接用默認(rèn)的工廠即可。
懂得原理以后,我們可以查看下,為什么最好不要直接用,比如:
Executors.newFixedThreadPool(3);
這個的主要原因就是這里面默認(rèn)隊列的最大值是Integer的最大值。
所以我們生產(chǎn)中需要自己配置線程池。因為默認(rèn)隊列的長度太長了,有可能會導(dǎo)致oom。就是內(nèi)存炸掉了。
這個在阿里的編程思想里面也有說明這一點:
這邊我們探討下,拒絕策略。4種策略。就是所有柜臺和等候區(qū)全部滿了。會如何處理。
用非常easy的代碼來過下,這塊的內(nèi)容:
1、AbortPolicy
import java.util.concurrent.*;public class VolatileTest { public static void main(String[] args) throws Exception { ExecutorService executorService = new ThreadPoolExecutor(2,5,1L,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); try { for (int i = 0; i < 9; i++) {executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+'t'+'辦理業(yè)務(wù)'); }}); } } catch (Exception e) { e.printStackTrace(); } finally { } }}
可以看到如果超出的話直接掛了,阻止正常運(yùn)行。
2、CallerRunsPolicy
輸出
發(fā)現(xiàn)有一個退回main線程,被main線程處理。即會把任務(wù)退回至調(diào)用者。
3、DiscardOldestPolicy
這個將會等待時間最久的任務(wù)丟掉。
4、DiscardPolicy
多出來的任務(wù)會全部丟掉。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. React+umi+typeScript創(chuàng)建項目的過程2. Warning: require(): open_basedir restriction in effect,目錄配置open_basedir報錯問題分析3. php網(wǎng)絡(luò)安全中命令執(zhí)行漏洞的產(chǎn)生及本質(zhì)探究4. JSP數(shù)據(jù)交互實現(xiàn)過程解析5. ASP.NET Core 5.0中的Host.CreateDefaultBuilder執(zhí)行過程解析6. 無線標(biāo)記語言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)第1/2頁7. php測試程序運(yùn)行速度和頁面執(zhí)行速度的代碼8. SharePoint Server 2019新特性介紹9. ASP調(diào)用WebService轉(zhuǎn)化成JSON數(shù)據(jù),附j(luò)son.min.asp10. 三個不常見的 HTML5 實用新特性簡介
