最近在看okhttp的原始碼,看著看著就看到了有執行緒池的地方,以前自己對這個東西就也就感到雲裡霧裡的,所以
想把執行緒池的知識點和原始碼完整的看一篇
1.執行緒池有什麼用?
a.重用執行緒池中存在的執行緒,避免因為執行緒的大量建立和銷毀所帶來的效能開銷 ,完成一項任務的時間t=建立線
2.threadpoolexcutor類詳解
threadpoolexcutor是執行緒池中最核心的類,所以要想弄懂執行緒池一定要弄懂這個類
(1)首先來了解一下構造方法:
public threadpoolexecutor(int corepoolsize,
int maximumpoolsize,
long keepalivetime,
timeunit unit,
blockingqueueworkqueue,
threadfactory threadfactory,
rejectedexecutionhandler handler);
接下來看看具體每個引數是什麼意思?
corepoolsize:核心執行緒池大小
maximumpoolsize:最大執行緒池大小
keepalivetime:當乙個執行緒無事可做,超過一定的時間(keepalivetime)時,執行緒池會判斷,
如果當前執行的執行緒數大於 corepoolsize,那麼這個執行緒就被停掉。
unit:keepalivetime時間單位
workqueue:阻塞任務佇列
threadfactory:新建執行緒工廠
handler: 當提交任務數超過maxmumpoolsize+workqueue之和時,任務會交給rejectedexecutionhandler來做拒絕處理
(2)blockingqueue詳解:用於儲存等待執行的執行緒任務的阻塞佇列
arrayblockingqueue(少):是乙個基於陣列結構的有界阻塞佇列,此佇列按 fifo(先進先出)原則對元素進行排序。
linkedblockingqueue:乙個基於鍊錶結構的阻塞佇列,此佇列按fifo (先進先出) 排序元素,吞吐量通常要高於arrayblockingqueue 靜態工廠方法executors.newfixedthreadpool()使用了這個佇列,如果不執行佇列的大小,那麼該
佇列就是乙個無界佇列,無界佇列的特徵見priorityblockingqueue
synchronousqueue:乙個不儲存元素的阻塞佇列。每個插入操作必須等到另乙個執行緒呼叫移除操作,否則插入操作一直處於阻塞狀態,它將任務直接提交給執行緒而不保持它們。在此,如果不存在可用於立即執行任務的執行緒,則試圖把任務加入佇列將失敗,因此會構造乙個新的執行緒
priorityblockingqueue(少):乙個具有優先順序的無限阻塞佇列,使用無界佇列將導致將導致在所有 corepoolsize 執行緒都忙時新任務在佇列中等待。這樣,建立的執行緒就不會超過 corepoolsize。(因此,maximumpoolsize和keepalivetime的值也就無效了)
(3)threadfactory作用:
執行緒工廠,主要用來根據提交的新任務建立執行緒物件
static class picassothreadfactory implements threadfactory
}
(4)threadpoolexcutor的執行步驟
①、當呼叫 execute() 方法新增乙個任務時,執行緒池會做如下判斷:
a. 如果正在執行的執行緒數量小於 corepoolsize,那麼馬上建立執行緒執行這個任務;
b. 如果正在執行的執行緒數量大於或等於 corepoolsize,那麼將這個任務放入佇列。
c. 如果這時候佇列滿了,而且正在執行的執行緒數量小於 maximumpoolsize,那麼還是要建立執行緒執行這個任務;
d. 如果佇列滿了,而且正在執行的執行緒數量大於或等於 maximumpoolsize,那麼執行緒池會丟擲異常,告訴呼叫者
「我不能再接受任務了」。
②、當乙個執行緒完成任務時,它會從佇列中取下乙個任務來執行。
③、當乙個執行緒無事可做,超過一定的時間(keepalivetime)時,執行緒池會判斷,如果當前執行的執行緒數大於
corepoolsize,那麼這個執行緒就被停掉。所以執行緒池的所有任務完成後,它最終會收縮到 corepoolsize 的大小。
這個過程說明,並不是先加入任務就一定會先執行。假設佇列大小為 4,corepoolsize為2,maximumpoolsize為6,
那麼當加入15個任務時,執行的順序類似這樣:首先執行任務 1、2,然後任務3~6被放入佇列。這時候佇列滿了,
任務7、8、9、10 會被馬上執行,而任務 11~15 則會丟擲異常。最終順序是:1、2、7、8、9、10、3、4、5、6。
當然這個過程是針對指定大小的arrayblockingqueue來說,如果無界佇列,那麼3-15的任務都會加到佇列 中
3.threadpoolexcutor的使用
(1)
newfixedthreadpool(2)
//指定了corepoolsize與maximumpoolsize為2
executorservicer pool=executors.newfixedthreadpool(2);
// 建立執行緒
thread t1 = new mythread();
thread t2 = new mythread();
thread t3 = new mythread();
// 將執行緒放入池中進行執行
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
// 關閉執行緒池
pool.shutdown();
private class mtthread extends thread
(2)單任務執行緒池newsinglethreadexecutor()
//只會有乙個執行緒執行
executorservice pool = executors.newsinglethreadexecutor();
(3).不限制大小,可變尺寸的執行緒池newcachedthreadpool()
//可根據需要建立新執行緒的執行緒池,但是在以前構造的執行緒可用時將重用它們。
executorservice pool = executors.newcachedthreadpool();
(4).
延遲線程池,newscheduledthre
adpool
// 建立乙個執行緒池,它可安排在給定延遲後執行命令或者定期地執行。
scheduledexecutorservice pool = executors.newscheduledthreadpool(2);
// 建立實現了runnable介面物件,thread物件當然也實現了runnable介面
thread t1 = new mythread();
thread t2 = new mythread();
thread t3 = new mythread();
// 將執行緒放入池中進行執行
pool.execute(t1);
// 使用延遲執行風格的方法
pool.schedule(t2, 1000, timeunit.milliseconds);
pool.schedule(t3, 10, timeunit.milliseconds);
// 關閉執行緒池
pool.shutdown();
以上就是executors類的四種靜態建立執行緒池的方法,如果不能滿足需求,還可以通過例項化threadpoolthread
來自定義執行緒池
(5)threadpoolexecutor中幾個重要的方法
① execute(runnable r):向執行緒池新增乙個執行緒任務
② future<?> submit(runnable r):向執行緒池新增乙個執行緒任務,可以返回任務執行結果
③ shutdown():關閉執行緒池,不接收新的任務,關閉後,正在等待執行的任務不受任何影響,會正常執行,無返回值!
④ shutdownnow():關閉執行緒池,也不接收新的task,並停止正等待執行的task(也就是說,
執行到一半的任務將正常執行下去),最終還會給你返回乙個正在等待執行但執行緒池關閉卻沒有被執行的task集合
我們執行runnable任務,他的run()方法是沒有返回值的,那如果我們想要執行完乙個任務,並且能夠拿到乙個返回值結果,那麼應該怎麼做呢?這個在我的另一篇部落格已經將的很清楚了就不重複講了future和callable詳解
Android執行緒池
executors jdk1.5之後的乙個新類,提供了一些靜態工廠,生成一些常用的執行緒池,threadpoolexecutor是executors類的底層實現 1.newsinglethreadexecutor 建立乙個單執行緒的執行緒池。這個執行緒池只有乙個執行緒在工作,也就是相當於單執行緒序列...
Android 執行緒池
threadpoolexecutor int corepoolsize,int maximumpoolsize,long keepalivetime,timeunit unit blockingqueueworkqueue,threadfactory threadfactory corepoolsi...
Android 執行緒池
適用於android的執行緒池 工具類 author yawei public class public executorservice diskio,executorservice networkio,executor mainthread,scheduledexecutorservice sch...