通過Thread創(chuàng)建線程的弊端
線程池
參數(shù)介紹
三個(gè)參數(shù)的關(guān)系:
1.當(dāng)前運(yùn)行的線程數(shù)小于corePoolSize時(shí),直接創(chuàng)建新線程處理任務(wù)备籽,即使其他線程空閑。
2.當(dāng)corePoolSize? <= 當(dāng)前線程數(shù) <= maximunPoolSize 绣版,只有當(dāng)workQueue滿的時(shí)候才創(chuàng)建新的線程處理任務(wù)胶台。
3.當(dāng)corePoolSize = maximumPoolSize時(shí),創(chuàng)建的線程池大小是固定的杂抽,如果有新任務(wù)提交诈唬,當(dāng)workQueue沒滿的時(shí)候,將請求放入workQueue缩麸,等待線程空閑后去取出任務(wù)進(jìn)行處理铸磅,如果滿了,還有新任務(wù)提交杭朱,則通過拒絕策略參數(shù)來指定策略去處理任務(wù)阅仔。
4.workQueue是線程池中保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列,當(dāng)提交新任務(wù)到線程池后弧械,線程池會(huì)根據(jù)當(dāng)前線程池中正在運(yùn)行的線程數(shù)量八酒,決定該任務(wù)的處理方式,總共有3種:直接切換刃唐,用無界隊(duì)列羞迷,用有界隊(duì)列。
——直接切換:這種方式常用的隊(duì)列是SynchronousQueue画饥;
——使用無界隊(duì)列:一般使用基于鏈表的阻塞隊(duì)列LinkedBlockingQueue衔瓮。如果使用這種方式,那么線程池中能夠創(chuàng)建的最大線程數(shù)就是corePoolSize抖甘,而maximunPoolSize就不會(huì)起作用了热鞍。當(dāng)線程池中所有的核心線程都是Running狀態(tài)時(shí),這時(shí)一個(gè)新的任務(wù)提交就會(huì)放入等待隊(duì)列中。
——使用有界隊(duì)列:一般使用ArrayBlockingQueue薇宠。使用該方式可以將線程池的最大線程數(shù)量限制為maximunPoolSize偷办,這樣能夠降低資源的消耗,但同時(shí)這種方式也使得線程池對線程的調(diào)度變得更加困難昼接,因?yàn)榫€程池和隊(duì)列的容量都是有限的值爽篷,所以要想使線程池處理任務(wù)的吞吐率達(dá)到一個(gè)相對合理的范圍悴晰,又想使線程調(diào)度相對簡單慢睡,并且還要盡可能的降低線程池對資源的消耗,就需要合理的設(shè)置這兩個(gè)數(shù)量铡溪。
? ? ? ? 如果要想降低系統(tǒng)資源的消耗(包括CPU的使用率漂辐,操作系統(tǒng)資源的消耗,上下文環(huán)境切換的開銷等)棕硫,可以設(shè)置較大的隊(duì)列容量和較小的線程池容量髓涯,但這樣也會(huì)降低線程處理任務(wù)的吞吐量。
? ? ? ? 如果提交的任務(wù)經(jīng)常發(fā)生堵塞哈扮,那么可以考慮通過調(diào)用setMaximunPoolSize()方法來重新設(shè)定線程池容量纬纪。如果隊(duì)列的容量設(shè)置的太小,通常需要將線程池的容量設(shè)置大一點(diǎn)滑肉,這樣CPU的使用率會(huì)相對的高一鞋包各。但如果線程池的容量設(shè)置的過大,則在提交的任務(wù)數(shù)量太多的情況下靶庙,并發(fā)量會(huì)增加问畅,那么線程之間的調(diào)度就是一個(gè)要考慮的問題,因?yàn)檫@樣反而有可能降低處理任務(wù)的吞吐量六荒。
拒絕策略:1.(默認(rèn)策略)直接拋出異常护姆。2.讓線程拋出異常。3.拋棄隊(duì)列中最早的任務(wù)掏击。4.拋棄當(dāng)前任務(wù)卵皂。