java Executors是為了更好地幫助我們使用多線程編程
使用線程池的初衷
在需要使用的線程很多的情況下頻繁創(chuàng)建線程沃饶、銷毀線程是比較麻煩的事情棠隐,每個(gè)線程去完成占用時(shí)間較短的任務(wù)是很浪費(fèi)資源的事情石抡,如何做到讓線程復(fù)用,使得線程完成任務(wù)之后并不馬上銷毀而是繼續(xù)完成其他任務(wù)
線程池類ThreadPoolExecutor
線程池類構(gòu)造器的構(gòu)造參數(shù):
corePoolSize:線程池的核心大小助泽,也可以理解為最小的線程池大小啰扛,線程數(shù)達(dá)到該標(biāo)準(zhǔn)時(shí),線程池自動(dòng)把要完成的任務(wù)放進(jìn)緩沖隊(duì)列
maximumPoolSize:最多能創(chuàng)建多少個(gè)線程报咳,也就是線程池的最大是多少
keepAliveTime:空余線程存活時(shí)間侠讯,指的是超過(guò)corePoolSize的空余線程達(dá)到多長(zhǎng)時(shí)間才進(jìn)行銷毀挖藏。如果線程池中線程數(shù)量少于corePoolSize時(shí)并不會(huì)觸發(fā)keepAliveTime的計(jì)算暑刃,但是超過(guò)線程池大小時(shí)當(dāng)有空余線程空閑的時(shí)間keepAliveTime那么會(huì)被終止
但是如果調(diào)用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數(shù)不大于corePoolSize時(shí)膜眠,keepAliveTime參數(shù)也會(huì)起作用岩臣,直到線程池中的線程數(shù)為0
workQueue:存儲(chǔ)等待執(zhí)行線程的工作隊(duì)列溜嗜。
threadFactory:創(chuàng)建線程的工廠,一般用默認(rèn)即可架谎。
handler:拒絕策略炸宵,當(dāng)工作隊(duì)列、線程池全已滿時(shí)如何拒絕新任務(wù)谷扣,默認(rèn)拋出異常会涎。
unit:keepAliveTime的時(shí)間單位
TimeUnit.DAYS;? ? ? ? ? ? ? //天
TimeUnit.HOURS;? ? ? ? ? ? //小時(shí)
TimeUnit.MINUTES;? ? ? ? ? //分鐘
TimeUnit.SECONDS;? ? ? ? ? //秒
TimeUnit.MILLISECONDS;? ? ? //毫秒
TimeUnit.MICROSECONDS;? ? ? //微妙
TimeUnit.NANOSECONDS;? ? ? //納秒
線程類的方法
execute()
submit()
shutdown()
shutdownNow()
線程池的關(guān)閉
shutdown():不會(huì)立即終止線程池,而是要等所有任務(wù)緩存隊(duì)列中的任務(wù)都執(zhí)行完后才終止概页,但再也不會(huì)接受新的任務(wù)
shutdownNow():立即終止線程池惰匙,并嘗試打斷正在執(zhí)行的任務(wù)铃将,并且清空任務(wù)緩存隊(duì)列劲阎,返回尚未執(zhí)行的任務(wù)
線程池工作流程
線程池工作流程:
1、如果當(dāng)前線程池中的線程數(shù)目小于corePoolSize奥此,則每來(lái)一個(gè)任務(wù)稚虎,就會(huì)創(chuàng)建一個(gè)線程去執(zhí)行這個(gè)任務(wù)
2偎捎、如果當(dāng)前線程池中的線程數(shù)目>=corePoolSize,則每來(lái)一個(gè)任務(wù)寻拂,會(huì)嘗試將其添加到任務(wù)緩存隊(duì)列當(dāng)中祭钉,若添加成功己沛,則該任務(wù)會(huì)等待空閑線程將其取出去執(zhí)行距境;若添加失數婀稹(一般來(lái)說(shuō)是任務(wù)緩存隊(duì)列已滿)诬滩,則會(huì)嘗試創(chuàng)建新的線程去執(zhí)行這個(gè)任務(wù)灭将,這個(gè)時(shí)候線程池中的線程數(shù)小于maximumPoolSize
3碱呼、如果當(dāng)前線程池中的線程數(shù)目達(dá)到maximumPoolSize愚臀,則會(huì)采取任務(wù)拒絕策略進(jìn)行處理姑裂,這個(gè)時(shí)候緩沖隊(duì)列不允許有新的任務(wù)了
4男旗、如果線程池中的線程數(shù)量大于 corePoolSize時(shí),如果某線程空閑時(shí)間超過(guò)keepAliveTime茴厉,線程將被終止什荣,直至線程池中的線程數(shù)目不大于corePoolSize;如果允許為核心池中的線程設(shè)置存活時(shí)間嗜闻,也就是allowCoreThreadTimeOut(true)桅锄,那么核心池中的線程空閑時(shí)間超過(guò)keepAliveTime友瘤,線程也會(huì)被終止
線程池使用
Java本身不建議我們直接使用ThreadPoolExecutor來(lái)初始化新的線程池,Executors提供以下四種靜態(tài)方法幫助我們初始化線程池束倍,也就是說(shuō)初始化一個(gè)線程池不一定需要配置那么多的參數(shù)
newCachedThreadPool 初始化一個(gè)可緩存的線程池,如果線程池長(zhǎng)度超過(guò)處理需要,可靈活回收空閑線程喂急,若無(wú)可回收笛求,則新建線程。線程池本身可以無(wú)限擴(kuò)大狡孔,也就是不存在緩沖隊(duì)列
newFixedThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池苗膝,可控制線程最大并發(fā)數(shù)辱揭,超出的線程會(huì)在隊(duì)列中等待病附。存在緩沖隊(duì)列
但是任務(wù)完成后線程池不會(huì)自動(dòng)關(guān)閉
newScheduledThreadPool創(chuàng)建大小無(wú)限但有核心容量的線程池完沪,并支持定時(shí)任務(wù)
newSingleThreadExecutor創(chuàng)建單例線程池創(chuàng)建一個(gè)單線程化的線程池覆积,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù),保證所有任務(wù)按照指定順序執(zhí)行写穴。