5、執行緒池知識點整理
1)、執行緒池型別:
newCachedThreadPool:建立一個可快取執行緒池,如果執行緒池長度超過處理需要,
可靈活回收空閒執行緒,若無可回收,則新建執行緒;
newFixedThreadPool:建立一個定長執行緒池,可控制執行緒最大併發數,
超出的執行緒會在佇列中等待;
newScheduledThreadPool:建立一個定長執行緒池,支援定時及週期性任務執行;
newSingleThreadExecutor:建立一個單執行緒化的執行緒池,它只會用
唯一的工作執行緒來執行任務,保證所有任務按照
指定順序(FIFO, LIFO, 優先順序)執行。
newSingleThreadScheduledExecutor:只有一個執行緒,用來排程執行將來的任務。
2)、執行緒池示例引數:
new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime,
TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
a)、第一個引數:corePoolSize,核心執行緒數量,
b)、第二個引數:int maximumPoolSize,執行緒池最大執行緒數
c)、第三個引數:long keepAliveTime,表示執行緒沒有任務執行時最多保持多久時間會終止
d)、第四個引數:TimeUnit unit,引數keepAliveTime的時間單位,有7種取值
e)、第五個引數:workQueue,一個阻塞佇列,通過execute方法提交的runnable物件
會儲存在該佇列中
其中阻塞佇列分為以下幾種:
(1)、ArrayBlockingQueue:基於陣列結構的有界阻塞佇列,按FIFO排序任務
(2)、LinkedBlockingQueue:基於連結串列結構的阻塞佇列,按FIFO排序任務,吞
吐量通常要高於ArrayBlockingQuene;是無界的,可以不指定佇列的大小,但是
預設是Integer.MAX_VALU。
(3)、SynchronousQueue:一個不儲存元素的阻塞佇列,每個插入操作必須等到
另一個執行緒呼叫移除操作,否則插入操作一直處於阻塞狀態,吞吐量通常要高於(2);
(4)、priorityBlockingQueue:具有優先順序的無界阻塞佇列;
3)、執行緒池的飽和策略
當阻塞佇列滿了,且沒有空閒的工作執行緒,如果繼續提交任務,必須採取一種策略處理該任務,
執行緒池提供了4種策略:
a)、ThreadPoolExcutor.AbortPolicy()——直接丟擲異常,預設操作;
b)、ThreadPoolExcutor.CallerRunsPolicy()——只用呼叫者所線上程來執行任務;
c)、ThreadPoolExcutor.DiscardOldersPolicy()——丟棄佇列裡最近的一個任務,
並執行當前任務;
d)、ThreadPoolExcutor.DiscardPolicy()——不處理,直接丟掉;
也可以根據應用場景實現RejectedExecutionHandler介面,自定義飽和策略。
4)、執行流程:
執行excute()方法之後
a)、判斷執行緒池存在核心執行緒的數量與corePoolSize的大小,
若小於corePoolSize,則呼叫addWorker函式建立新執行緒;
否則執行b;
b)、判斷等待佇列是否已滿,若未滿,則加入佇列中;否則執行c;
c)、判斷執行緒池是否已滿,若未滿,則建立執行緒執行任務;否則執行d;
d)、按照飽和策略,處理任務
部分原始碼(核心在addWorker):
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
複製程式碼
流程圖(網上找的):