溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

java中ThreadPoolExecutor的使用方法

發(fā)布時(shí)間:2021-07-13 10:21:35 來(lái)源:億速云 閱讀:520 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要講解了“java中ThreadPoolExecutor的使用方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“java中ThreadPoolExecutor的使用方法”吧!

ThreadPoolExecutor也就是線程池。它就是Java為我們開(kāi)發(fā)多線程程序時(shí)提供的一個(gè)開(kāi)發(fā)框架。它可以統(tǒng)一的管理線程的創(chuàng)建、銷(xiāo)毀、優(yōu)化、監(jiān)控等,在使用線程池時(shí)比我們直接使用原始的線程類(lèi)更加方便。既然線程池這么方便,那它到底是怎么實(shí)現(xiàn)上述的功能呢?下面我們先看一下當(dāng)用線程池啟動(dòng)一個(gè)線程時(shí)它的流程圖。

java中ThreadPoolExecutor的使用方法

線程池的處理流程如下:

當(dāng)我們用線程池啟動(dòng)一個(gè)任務(wù)時(shí),線程池首先會(huì)檢查核心線程池里面的線程數(shù)是否已經(jīng)超過(guò)corePoolSize。如果沒(méi)有超過(guò)則創(chuàng)建一個(gè)新的線程執(zhí)行任務(wù)。如果超過(guò)了,那么將當(dāng)前執(zhí)行的任務(wù)添加到線程池的工作隊(duì)列中,但在加入之前會(huì)先檢查工作隊(duì)列是否已經(jīng)滿了,如果工作隊(duì)列已經(jīng)滿了,那么此時(shí)它會(huì)檢查線程池中的線程是否超過(guò)了允許的最大數(shù)量。如果沒(méi)有超過(guò)則創(chuàng)建線程執(zhí)行任務(wù),如果超過(guò)了最大數(shù)量,則按照無(wú)法執(zhí)行的策略處理。

線程池的創(chuàng)建:在創(chuàng)建ThreadPoolExecutor時(shí),會(huì)需要傳遞幾個(gè)必要的參數(shù),下面我們?cè)敿?xì)看一下它們每個(gè)參數(shù)所代表的含義。

  • corePoolSize(初始化的空閑線程):當(dāng)我們創(chuàng)建ThreadPoolExecutor對(duì)象時(shí),可以用corePoolSize參數(shù)設(shè)置線程池的初始化線程數(shù),也就是空閑線程,當(dāng)線程池中的線程數(shù)量小于corePoolSize時(shí),線程池會(huì)重新創(chuàng)建一個(gè)新的線程來(lái)處理任務(wù),而不是直接使用線程池中的空閑線程。

  • maximumPoolSize(線程池最大數(shù)量):線程池允許創(chuàng)建的最大線程數(shù)。也就最大并發(fā)數(shù),也就是說(shuō)線程池允許多少個(gè)線程同時(shí)執(zhí)行。

  • keepAliveTime(線程活動(dòng)保持時(shí)間):當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),用此參數(shù)設(shè)置空閑線程等待新任務(wù)的時(shí)間。在此時(shí)間內(nèi)如果線程沒(méi)有接收到新的任務(wù),那么當(dāng)前線程會(huì)被銷(xiāo)毀。

  • TimeUnit(線程活動(dòng)保持時(shí)間的單位):可選的單位有天(DAYS)、小時(shí)(HOURS)、分鐘(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和納秒(NANOSECONDS,千分之一微秒)。

  • BlockingQueue(線程池中的任務(wù)隊(duì)列),當(dāng)線程池中線程數(shù)大于corePoolSize時(shí),新提交的任務(wù)會(huì)被保存到任務(wù)隊(duì)列中。在線程池中主要有4種不同的任務(wù)隊(duì)列。

  1. ArrayBlockingQueue:是基于數(shù)組結(jié)構(gòu)的任務(wù)隊(duì)列。此隊(duì)列按先進(jìn)先出的原則對(duì)任務(wù)進(jìn)行排序。

  2. LinkedBlockingQueue:是基于鏈表結(jié)構(gòu)的任務(wù)隊(duì)列。此隊(duì)列也是按先進(jìn)先出的原則對(duì)任務(wù)進(jìn)行排序。但性能通常要比ArrayBlockingQueue高

  3. SynchronousQueue:一個(gè)不存儲(chǔ)元素的任務(wù)隊(duì)列。每個(gè)插入操作必須等到另一個(gè)線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài)。

  4. PriorityBlockingQueue:是一個(gè)具有優(yōu)先級(jí)的任務(wù)隊(duì)列。此隊(duì)列中的元素必須能夠比較。

  • ThreadFactory():創(chuàng)建線程的線程工廠。

  • RejectedExecutionHandler(飽和策略 ):當(dāng)線程池中的線程數(shù)大于maximumPoolSize時(shí),線程池就不能在處理任何任務(wù)了,這時(shí)線程池會(huì)拋出異常。原因就是這個(gè)策略默認(rèn)情況下是AbortPolicy:表示無(wú)法處理新任務(wù)時(shí)拋出異常。除此之外還有其它幾種策略:

  1. AbortPolicy:直接拋出異常。 

  2. CallerRunsPolicy:只用調(diào)用者所在線程來(lái)運(yùn)行任務(wù)。 

  3. DiscardOldestPolicy:丟棄隊(duì)列里最近的一個(gè)任務(wù),并執(zhí)行當(dāng)前任務(wù)。 

  4. DiscardPolicy:不處理,丟棄掉。

下面我們用具體的代碼來(lái)詳細(xì)說(shuō)明一下ThreadPoolExecutor的使用。

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

按照上面的分析,因?yàn)槲覀儎?chuàng)建ThreadPoolExecutor對(duì)象時(shí)初始化的空閑線程是2個(gè),并且我們添加到線程池中的數(shù)量也是2個(gè),所以當(dāng)前任務(wù)是由核心線程池執(zhí)行的任務(wù)并不會(huì)將任務(wù)添加到對(duì)列中。如果我在繼續(xù)向線程池中提交任務(wù),那么因?yàn)槌^(guò)了我們?cè)O(shè)置的corePoolSize數(shù)量,所以此時(shí)隊(duì)列中就有了我們新提交的任務(wù)了。

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

因?yàn)槲覀冊(cè)O(shè)置的線程池的最大線程數(shù)是3也就是maximumPoolSize的值。如果超過(guò)這個(gè)值,并且我們沒(méi)有更改相應(yīng)的飽和策略,那么此時(shí)就會(huì)拋出異常信息。

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

我們發(fā)現(xiàn)程序居然沒(méi)有報(bào)錯(cuò),這是因?yàn)槭裁茨?。這是因?yàn)閰?shù)maximumPoolSize的作是指線程池最大能允許的最大并發(fā)數(shù)是3也就是說(shuō)同時(shí)可以執(zhí)行3個(gè)線程,但是我們別忘了線程池中還有一個(gè)隊(duì)列呢。隊(duì)列里存儲(chǔ)的就是將要被執(zhí)行的任務(wù),只是現(xiàn)在已經(jīng)超過(guò)了最大并發(fā)數(shù)所以隊(duì)列里的任務(wù)只能等待線程池中有其它任務(wù)執(zhí)行完后,它才可以執(zhí)行。所以此時(shí)線程池中允許我們提交任務(wù)的最大數(shù)就是maximumPoolSize加上隊(duì)列的數(shù)量。但如果我們繼續(xù)向線程池有添加任務(wù),那么線程池就會(huì)報(bào)錯(cuò)了,因?yàn)橐呀?jīng)沒(méi)有地方存儲(chǔ)新任務(wù)了,隊(duì)列也已經(jīng)滿了,所以只能走飽和策略的默認(rèn)策略就是拋出異常。

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

下面我們修改一下線程池的飽和策略。

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

線程池中相關(guān)方法的介紹

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

java中ThreadPoolExecutor的使用方法

taskCount:線程池需要執(zhí)行的任務(wù)數(shù)。雖然我們向線程池中提交了5個(gè)任務(wù),但第5個(gè)任務(wù)并不是由線程池執(zhí)行的,是我們修改了飽和策略自己執(zhí)行的。所以此值返回結(jié)果是4。 

completedTaskCount:線程池中完成的任務(wù)數(shù)。 

largestPoolSize:線程池中曾經(jīng)創(chuàng)建過(guò)的最大線程數(shù)。也就是有多少個(gè)線程同是執(zhí)行,也叫最大并發(fā)數(shù)。 

getPoolSize:線程池中的線程數(shù)。如果線程池不銷(xiāo)毀,那么線程池里的線程也不會(huì)自動(dòng)銷(xiāo)毀。 

getActiveCount:活動(dòng)的線程數(shù)。

感謝各位的閱讀,以上就是“java中ThreadPoolExecutor的使用方法”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)java中ThreadPoolExecutor的使用方法這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI