歡迎您光臨本站 註冊首頁

Java手動配置線程池過程詳解

←手機掃碼閱讀     ljg58026 @ 2020-05-13 , reply:0

線程池中,常見有涉及到的:
ExecutorService executorService = Executors.newSingleThreadExecutor();
ExecutorService executorService1 = Executors.newCachedThreadPool();
ExecutorService executorService2 = Executors.newFixedThreadPool(3);
關於Executors和ExecutorService從記憶上類似於Collections和List。
但是以上幾種其實不建議使用。最好可以通過自己手動配置ThreadPoolExecutor的形式。
我先創建一個demo:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue

(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() );
涉及7個參數,按順序分別是
int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler
具體我首先需要結合參數解釋下線程池的執行原理:
畫了張圖:
如果我用銀行辦理業務示例說明如下:
1、首先銀行裡面有兩個櫃檯,這就是核心線程數(7大參數之一)。
2、然後隨著客戶的增加,可能這個兩個櫃檯滿了,然後就要請用戶到等候區裡面進行等待。這個等候區就是相當於阻塞隊列(七大參數之一)。
3、然後緊接著客戶越來越多,連阻塞隊列都撐不住了,這個時候,就要請求,上面的領導進行多增加櫃檯的操作,這個時候,可能加了三個櫃檯,現在就有5個櫃檯了。這個時候最大的線程數(七大參數之一)就是5了。
4、但是這個時候可能客戶又越來越多,這個時候新加的櫃檯也受不了,就要開始有拒絕策略了(七大參數之一)
5、然後過了一段時間,慢慢的,客戶越來越少了,這個時候,發現漸漸的,櫃檯空餘出來了。KeepAliveTime(七大參數之一,加上單位,合計兩個參數)指當線程數大於核心線程數時,此為終止前多餘的空閒線程等待新任務的最長時間。
6、還有一個參數是工廠,這個我們不做深入研究,直接用默認的工廠即可。
懂得原理以後,我們可以查看下,為什麼最好不要直接用,比如:
Executors.newFixedThreadPool(3);
這個的主要原因就是這裡面默認隊列的最大值是Integer的最大值。
所以我們生產中需要自己配置線程池。因為默認隊列的長度太長了,有可能會導致oom。就是內存炸掉了。
這個在阿里的編程思想裡面也有說明這一點:
這邊我們探討下,拒絕策略。4種策略。就是所有櫃檯和等候區全部滿了。會如何處理。
用非常easy的代碼來過下,這塊的內容:
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(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()+" "+"辦理業務"); } }); } } catch (Exception e) { e.printStackTrace(); } finally { } } }
可以看到如果超出的話直接掛了,阻止正常運行。
2、CallerRunsPolicy
輸出
發現有一個退回main線程,被main線程處理。即會把任務退回至調用者。
3、DiscardOldestPolicy
這個將會等待時間最久的任務丟掉。
4、DiscardPolicy
多出來的任務會全部丟掉。


[ljg58026 ] Java手動配置線程池過程詳解已經有267次圍觀

http://coctec.com/docs/java/show-post-234246.html