這篇文章主要講解了“什么是線程池”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“什么是線程池”吧!
創(chuàng)新互聯(lián)建站長期為1000多家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為東興企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站建設,東興網(wǎng)站改版等技術服務。擁有十年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
(I:代表接口,C:代表實現(xiàn)類)I:Executor I:ExecutorService C:AbstractExecutorService C:ThreadPoolExecutor
該類的主要構造函數(shù)如下:
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
corePoolSize:核心線程池的大小。如果核心線程池有空閑位置,新的任務進來就會被核心線程池新建一個線程執(zhí)行,執(zhí)行完畢后不會銷毀線程,線程會進入緩存隊列等待再次被運行。
maximunPoolSize:最大的線程數(shù)量。如果核心線程池和緩存隊列都已經(jīng)滿了,新的任務進來就會創(chuàng)建新的線程來執(zhí)行。但是數(shù)量不能超過maximunPoolSize,否側會采取拒絕接受任務策略,我們下面會具體分析。
keepAliveTime:非核心線程能夠空閑的最長時間,超過時間,線程終止。這個參數(shù)默認只有在線程數(shù)量超過核心線程池大小時才會起作用。只要線程數(shù)量不超過核心線程大小,就不會起作用。
unit:時間單位,和keepAliveTime配合使用。
workQueue: 緩存隊列,用來存放等待被執(zhí)行的任務,有以下取值:
1、ArrayBlockingQueue; 有界阻塞隊列,詳見文章:ArrayBlockingQueue詳解
2、LinkedBlockingQueue; 無界阻塞隊列,詳見文章:LinkedBlockingQueue詳解
3、SynchronousQueue; 無緩沖阻塞隊列 ,詳見文章:SynchronousQueue詳解
threadFactory:線程工廠,用來創(chuàng)建線程,默認new Executors.DefaultThreadFactory();
handler: 線程拒絕策略。當創(chuàng)建的線程超出maximumPoolSize值,且緩沖隊列已滿時,對新提交任務的處理策略,有以下4種取值,我們結合代碼分析
1、ThreadPoolExecutor.AbortPolicy 無視任務(也就是丟棄任務),并通過拋異常告知調用者“我拒絕接收新任務”
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { //這里直接拋出異常,可理解為:無視任務(也就是丟棄任務),并通過拋異常告知調用者“我拒絕接收新任務” throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); }
2、ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不做任何處理。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { //這里是空實現(xiàn),也就是丟棄任務,不作任何的處理 //這會導致:雖然此策略被觸發(fā),但調用者根本不知道它提交進來的任務,最終到底有沒有被執(zhí)行 }
3、ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,嘗試執(zhí)行新任務。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //判斷線程池是否被關閉了 e.getQueue().poll();//丟棄隊列最前面的任務 e.execute(r); //嘗試執(zhí)行新任務 } }
4、ThreadPoolExecutor.CallerRunsPolicy:由調用線程處理該任務
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { //判斷線程池是否被關閉了 r.run(); //調用線程直接調用run()方法,執(zhí)行其代碼邏輯 } }
基于ThreadPoolExecutor 的構造參數(shù)如此之多,JDK為我們提供了Executors類,通過它我們可以簡單的創(chuàng)建出四種類型的線程池,一般場景下夠用了。
1.3.1、固定大小線程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor( nThreads, // corePoolSize nThreads,// maximumPoolSize 0L, TimeUnit.MILLISECONDS,// keepAliveTime=0秒 new LinkedBlockingQueue<Runnable>()// 利用無界阻塞隊列 ); }
參數(shù):corePoolSize = 固定值,maximumPoolSize = 固定值,keepAliveTime = 0秒 ,workQueue = LinkedBlockingQueue 無界阻塞隊列
分析:
1、corePoolSize 和 maximumPoolSize 都為 nThreads 一個固定值,說明此線程池中都是核心線程,keepAliveTime為非核心線程空閑時間,該線程池中不存在非核心線程,所以參數(shù)keepAliveTime在此處無效;
2、new LinkedBlockingQueue<Runnable>() :緩存隊列用的無界阻塞隊列,當核心池子里的線程都在忙的時候,新進來的任務被放到此隊列中;一旦有空閑的線程了,該線程就會從隊列里去拿任務執(zhí)行;
3、缺點:因為用的是無界隊列,所以當 nThreads 個線程一直被占用的情況下,同時又不斷的有新任務進來,就有可能導致OOM問題;
1.3.2、單個線程的線程池
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, // corePoolSize,maximumPoolSize 0L, TimeUnit.MILLISECONDS,// keepAliveTime=0秒 new LinkedBlockingQueue<Runnable>())// 利用無界阻塞隊列 ); }
參數(shù):corePoolSize = 1,maximumPoolSize = 1,keepAliveTime = 0秒 ,workQueue = LinkedBlockingQueue 無界阻塞隊列
分析:
1、corePoolSize 和 maximumPoolSize 都為1,此線程池只有一個核心線程,同上,參數(shù)keepAliveTime在此處無效;
2、new LinkedBlockingQueue<Runnable>() :緩存隊列用的無界阻塞隊列,當僅有的一個核心線程在忙的時候,新進來的任務被放到此隊列中;待線程空閑了,就會從隊列里去拿任務執(zhí)行;
3、缺點:因為用的是無界隊列,所以當核心線程一直被占用的情況下,同時又不斷的有新任務進來,就有可能導致OOM問題;
4、有沒有注意到,這里為什么用了一個FinalizableDelegatedExecutorService類呢?
見文章:關于newSingleThreadExecutor中的FinalizableDelegatedExecutorService源碼分析
1.3.3、緩存線程池
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE,// corePoolSize,maximumPoolSize 60L, TimeUnit.SECONDS,// keepAliveTime=60秒 new SynchronousQueue<Runnable>());// 同步阻塞隊列 }
參數(shù):corePoolSize = 0,maximumPoolSize = 無限大,keepAliveTime = 60秒(重要) ,workQueue = SynchronousQueue 無緩沖阻塞隊列
分析:一個可以根據(jù)需要創(chuàng)建線程的線程池,此線程池中所有線程都為非核心線程,且最大空閑時間為60秒,最多可以創(chuàng)建Integer.MAX_VALUE 個線程(2^31次方,21億多,可以視為無限);SynchronousQueue 為無緩沖阻塞隊列,也就是此隊列里不會緩沖新的任務,有新任務進來時,如果無空閑線程,就會新創(chuàng)建一個線程;如果有空閑線程,就會使用空閑線程;所以此線程池適合執(zhí)行一些執(zhí)行周期短的任務。
感謝各位的閱讀,以上就是“什么是線程池”的內容了,經(jīng)過本文的學習后,相信大家對什么是線程池這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!
網(wǎng)站欄目:什么是線程池
分享鏈接:http://www.rwnh.cn/article2/jdjhic.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供ChatGPT、品牌網(wǎng)站建設、靜態(tài)網(wǎng)站、營銷型網(wǎng)站建設、關鍵詞優(yōu)化、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)