通過(guò)Thread創(chuàng)建線(xiàn)程的弊端

線(xiàn)程池

參數(shù)介紹

三個(gè)參數(shù)的關(guān)系:
1.當(dāng)前運(yùn)行的線(xiàn)程數(shù)小于corePoolSize時(shí),直接創(chuàng)建新線(xiàn)程處理任務(wù),即使其他線(xiàn)程空閑。
2.當(dāng)corePoolSize? <= 當(dāng)前線(xiàn)程數(shù) <= maximunPoolSize ,只有當(dāng)workQueue滿(mǎn)的時(shí)候才創(chuàng)建新的線(xiàn)程處理任務(wù)。
3.當(dāng)corePoolSize = maximumPoolSize時(shí),創(chuàng)建的線(xiàn)程池大小是固定的,如果有新任務(wù)提交,當(dāng)workQueue沒(méi)滿(mǎn)的時(shí)候,將請(qǐng)求放入workQueue,等待線(xiàn)程空閑后去取出任務(wù)進(jìn)行處理,如果滿(mǎn)了,還有新任務(wù)提交,則通過(guò)拒絕策略參數(shù)來(lái)指定策略去處理任務(wù)。
4.workQueue是線(xiàn)程池中保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列,當(dāng)提交新任務(wù)到線(xiàn)程池后,線(xiàn)程池會(huì)根據(jù)當(dāng)前線(xiàn)程池中正在運(yùn)行的線(xiàn)程數(shù)量,決定該任務(wù)的處理方式,總共有3種:直接切換,用無(wú)界隊(duì)列,用有界隊(duì)列。
——直接切換:這種方式常用的隊(duì)列是SynchronousQueue;
——使用無(wú)界隊(duì)列:一般使用基于鏈表的阻塞隊(duì)列LinkedBlockingQueue。如果使用這種方式,那么線(xiàn)程池中能夠創(chuàng)建的最大線(xiàn)程數(shù)就是corePoolSize,而maximunPoolSize就不會(huì)起作用了。當(dāng)線(xiàn)程池中所有的核心線(xiàn)程都是Running狀態(tài)時(shí),這時(shí)一個(gè)新的任務(wù)提交就會(huì)放入等待隊(duì)列中。
——使用有界隊(duì)列:一般使用ArrayBlockingQueue。使用該方式可以將線(xiàn)程池的最大線(xiàn)程數(shù)量限制為maximunPoolSize,這樣能夠降低資源的消耗,但同時(shí)這種方式也使得線(xiàn)程池對(duì)線(xiàn)程的調(diào)度變得更加困難,因?yàn)榫€(xiàn)程池和隊(duì)列的容量都是有限的值,所以要想使線(xiàn)程池處理任務(wù)的吞吐率達(dá)到一個(gè)相對(duì)合理的范圍,又想使線(xiàn)程調(diào)度相對(duì)簡(jiǎn)單,并且還要盡可能的降低線(xiàn)程池對(duì)資源的消耗,就需要合理的設(shè)置這兩個(gè)數(shù)量。
? ? ? ? 如果要想降低系統(tǒng)資源的消耗(包括CPU的使用率,操作系統(tǒng)資源的消耗,上下文環(huán)境切換的開(kāi)銷(xiāo)等),可以設(shè)置較大的隊(duì)列容量和較小的線(xiàn)程池容量,但這樣也會(huì)降低線(xiàn)程處理任務(wù)的吞吐量。
? ? ? ? 如果提交的任務(wù)經(jīng)常發(fā)生堵塞,那么可以考慮通過(guò)調(diào)用setMaximunPoolSize()方法來(lái)重新設(shè)定線(xiàn)程池容量。如果隊(duì)列的容量設(shè)置的太小,通常需要將線(xiàn)程池的容量設(shè)置大一點(diǎn),這樣CPU的使用率會(huì)相對(duì)的高一鞋。但如果線(xiàn)程池的容量設(shè)置的過(guò)大,則在提交的任務(wù)數(shù)量太多的情況下,并發(fā)量會(huì)增加,那么線(xiàn)程之間的調(diào)度就是一個(gè)要考慮的問(wèn)題,因?yàn)檫@樣反而有可能降低處理任務(wù)的吞吐量。

拒絕策略:1.(默認(rèn)策略)直接拋出異常。2.讓線(xiàn)程拋出異常。3.拋棄隊(duì)列中最早的任務(wù)。4.拋棄當(dāng)前任務(wù)。