更新時間:2020-06-22 12:56:27 來源:動力節(jié)點(diǎn) 瀏覽2406次
隨著當(dāng)今處理器中可用的核心數(shù)量的增加,隨著對實(shí)現(xiàn)更高吞吐量的需求的不斷增長,多線程API變得非常流行。Java提供了自己的多線程框架,稱為Executor框架.

1.Executor框架是什么?
Executor框架包含一組用于有效管理工作線程的組件。Executor API通過Executors將任務(wù)的執(zhí)行與要執(zhí)行的實(shí)際任務(wù)解耦。這是生產(chǎn)者-消費(fèi)者模式的一種實(shí)現(xiàn)。
java.util.concurrent.Executors提供了用于創(chuàng)建工作線程的線程池的工廠方法。
為了使用Executor框架,我們需要創(chuàng)建一個線程池并提交任務(wù)給它以供執(zhí)行。Executor框架的工作是調(diào)度和執(zhí)行已提交的任務(wù)并從線程池中拿到返回的結(jié)果。
浮現(xiàn)于腦海中的一個基本的問題是,當(dāng)我們創(chuàng)建java.lang.Thread的對象或調(diào)用實(shí)現(xiàn)了Runnable/Callable接口來達(dá)到的程序的并行性時,為什么需要線程池?
答案來源于兩個基本面:
為新任務(wù)創(chuàng)建新的線程會存在額外的線程創(chuàng)建以及銷毀的開銷。管理這些線程的生命周期會明顯增加CPU的執(zhí)行時間。
不進(jìn)行任何限制地為每個進(jìn)程創(chuàng)建線程會導(dǎo)致創(chuàng)建大量線程。這些線程會占用大量內(nèi)存并引起資源的浪費(fèi)。當(dāng)一個線程利用完CPU的時間片后另一個線程即將利用CPU的時間片時,CPU會花費(fèi)大量的時間來切換線程的上下文。
所有的這些因素都會導(dǎo)致系統(tǒng)的吞吐量下降。線程池通過保持線程一直存活并重用這些線程來克服這個問題。當(dāng)提交到線程池中的任務(wù)多于正在執(zhí)行的線程時,那些多余的任務(wù)將被放到隊(duì)列中。一旦執(zhí)行任務(wù)的線程有空閑的了,它們會從隊(duì)列中取下一個任務(wù)來執(zhí)行。對于JDK提供的現(xiàn)成的executors此任務(wù)隊(duì)列基本是無界的。
2.Executors的類型
現(xiàn)在我們已經(jīng)了解了executors是什么,讓我們來看看不同類型的executors。
2.1 SingleThreadExecutor
此線程池executor只有一個線程。它用于以順序方式的形式執(zhí)行任務(wù)。如果此線程在執(zhí)行任務(wù)時因異常而掛掉,則會創(chuàng)建一個新線程來替換此線程,后續(xù)任務(wù)將在新線程中執(zhí)行。
ExecutorService executorService=Executors.newSingleThreadExecutor()
2.2 FixedThreadPool(n)
顧名思義,它是一個擁有固定數(shù)量線程的線程池。提交給executor的任務(wù)由固定的n個線程執(zhí)行,如果有更多的任務(wù),它們存儲在LinkedBlockingQueue里。這個數(shù)字n通常跟底層處理器支持的線程總數(shù)有關(guān)。
ExecutorService executorService=Executors.newFixedThreadPool(4);
2.3 CachedThreadPool
該線程池主要用于執(zhí)行大量短期并行任務(wù)的場景。與固定線程池不同,此線程池的線程數(shù)不受限制。如果所有的線程都在忙于執(zhí)行任務(wù)并且又有新的任務(wù)到來了,這個線程池將創(chuàng)建一個新的線程并將其提交到executor。只要其中一個線程變?yōu)榭臻e,它就會執(zhí)行新的任務(wù)。如果一個線程有60秒的時間都是空閑的,它們將被結(jié)束生命周期并從緩存中刪除。
但是,如果管理得不合理,或者任務(wù)不是很短的,則線程池將包含大量的活動線程。這可能導(dǎo)致資源紊亂并因此導(dǎo)致性能下降。
ExecutorService executorService=Executors.newCachedThreadPool();
2.4 ScheduledExecutor
當(dāng)我們有一個需要定期運(yùn)行的任務(wù)或者我們希望延遲某個任務(wù)時,就會使用此類型的executor。
ScheduledExecutorService scheduledExecService=Executors.newScheduledThreadPool(1);
可以使用scheduleAtFixedRate或scheduleWithFixedDelay在ScheduledExecutor中定期的執(zhí)行任務(wù)。
scheduledExecService.scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)
scheduledExecService.scheduleWithFixedDelay(Runnable command,long initialDelay,long period,TimeUnit unit)
這兩種方法的主要區(qū)別在于它們對連續(xù)執(zhí)行定期任務(wù)之間的延遲的應(yīng)答。
scheduleAtFixedRate:無論前一個任務(wù)何時結(jié)束,都以固定間隔執(zhí)行任務(wù)。
scheduleWithFixedDelay:只有在當(dāng)前任務(wù)完成后才會啟動延遲倒計(jì)時。

以上就是動力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對“JAVA并發(fā)框架視頻之Executor”的內(nèi)容進(jìn)行的回答,希望對大家有所幫助,如有疑問,請?jiān)诰€咨詢,有專業(yè)老師隨時為你服務(wù)。
相關(guān)閱讀

初級 202925

初級 203221

初級 202629

初級 203743