1. 程式人生 > >通過Executors建立執行緒池存在的弊端,如何使用ThreadPoolExecutor建立執行緒池

通過Executors建立執行緒池存在的弊端,如何使用ThreadPoolExecutor建立執行緒池

Java通過Executors提供四種執行緒池,分別為:

1)newCachedThreadPool 建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。2)newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超出的執行緒會在佇列中等待。3)newScheduledThreadPool 建立一個定長執行緒池,支援定時及週期性任務執行。4)SingleThreadPool 建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先順序)執行。

阿里開發手冊上寫著關於執行緒建立的問題:

【強制】執行緒池不允許使用Executors去建立,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。

以前是沒有給說明的,在終結版中給出了為什麼這麼做的原因:

說明:Executors返回的執行緒池物件的弊端如下:

1FixedThreadPool SingleThreadPool

允許的請求佇列長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致OOM。

2CachedThreadPool ScheduledThreadPool :

允許建立的執行緒數量為Integer.MAX_VALUE,可能會建立大量的執行緒,從而導致OOM。

// corePoolSize 核心執行緒池大小
// maximumPoolSize 執行緒池最大容量大小
// keepAliveTime 執行緒池空閒時,執行緒存活的時間
// TimeUnit 時間單位
// ThreadFactory 執行緒工廠,Executors.defaultThreadFactory(),也可以使用下面的

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
// BlockingQueue任務佇列--LinkedBlockingDeque是雙向連結串列實現的雙向併發阻塞佇列。該阻塞佇列同時支援FIFO和FILO兩種操作方式,即可以從佇列的頭和尾同時操作(插入/刪除);並且,該阻塞佇列是支援執行緒安全。
// RejectedExecutionHandler 執行緒拒絕策略
ExecutorService threadPool = new ThreadPoolExecutor(1, 5, 30, TimeUnit.MILLISECONDS,
			new LinkedBlockingDeque<Runnable>(1024), Executors.defaultThreadFactory(),
			new ThreadPoolExecutor.AbortPolicy());