自帶線(xiàn)程池

關(guān)于線(xiàn)程和線(xiàn)程池的學(xué)習(xí)授霸,我們可以從以下幾個(gè)方面入手:

第一巡验,什么是線(xiàn)程,線(xiàn)程和進(jìn)程的區(qū)別是什么

第二碘耳,線(xiàn)程中的基本概念显设,線(xiàn)程的生命周期

第三,單線(xiàn)程和多線(xiàn)程

第四辛辨,線(xiàn)程池的原理解析

第五捕捂,常見(jiàn)的幾種線(xiàn)程池的特點(diǎn)以及各自的應(yīng)用場(chǎng)景

一瑟枫、什么是線(xiàn)程

線(xiàn)程,程序執(zhí)行流的最小執(zhí)行單位指攒,是行程中的實(shí)際運(yùn)作單位慷妙,經(jīng)常容易和進(jìn)程這個(gè)概念混淆。那么允悦,線(xiàn)程和進(jìn)程究竟有什么區(qū)別呢膝擂?首先,進(jìn)程是一個(gè)動(dòng)態(tài)的過(guò)程隙弛,是一個(gè)活動(dòng)的實(shí)體架馋。簡(jiǎn)單來(lái)說(shuō),一個(gè)應(yīng)用程序的運(yùn)行就可以被看做是一個(gè)進(jìn)程全闷,而線(xiàn)程叉寂,是運(yùn)行中的實(shí)際的任務(wù)執(zhí)行者∽苤椋可以說(shuō)屏鳍,進(jìn)程中包含了多個(gè)可以同時(shí)運(yùn)行的線(xiàn)程。

二姚淆、線(xiàn)程的生命周期

線(xiàn)程的生命周期可以利用以下的圖解來(lái)更好的理解:

第一步孕蝉,是用new Thread()的方法新建一個(gè)線(xiàn)程,在線(xiàn)程創(chuàng)建完成之后腌逢,線(xiàn)程就進(jìn)入了就緒(Runnable)狀態(tài),此時(shí)創(chuàng)建出來(lái)的線(xiàn)程進(jìn)入搶占CPU資源的狀態(tài)超埋,當(dāng)線(xiàn)程搶到了CPU的執(zhí)行權(quán)之后搏讶,線(xiàn)程就進(jìn)入了運(yùn)行狀態(tài)(Running),當(dāng)該線(xiàn)程的任務(wù)執(zhí)行完成之后或者是非常態(tài)的調(diào)用的stop()方法之后霍殴,線(xiàn)程就進(jìn)入了死亡狀態(tài)媒惕。而我們?cè)趫D解中可以看出,線(xiàn)程還具有一個(gè)則色的過(guò)程来庭,這是怎么回事呢妒蔚?當(dāng)面對(duì)以下幾種情況的時(shí)候,容易造成線(xiàn)程阻塞月弛,第一種肴盏,當(dāng)線(xiàn)程主動(dòng)調(diào)用了sleep()方法時(shí),線(xiàn)程會(huì)進(jìn)入則阻塞狀態(tài)帽衙,除此之外菜皂,當(dāng)線(xiàn)程中主動(dòng)調(diào)用了阻塞時(shí)的IO方法時(shí),這個(gè)方法有一個(gè)返回參數(shù)厉萝,當(dāng)參數(shù)返回之前恍飘,線(xiàn)程也會(huì)進(jìn)入阻塞狀態(tài)榨崩,還有一種情況,當(dāng)線(xiàn)程進(jìn)入正在等待某個(gè)通知時(shí)章母,會(huì)進(jìn)入阻塞狀態(tài)母蛛。那么,為什么會(huì)有阻塞狀態(tài)出現(xiàn)呢乳怎?我們都知道,CPU的資源是十分寶貴的彩郊,所以,當(dāng)線(xiàn)程正在進(jìn)行某種不確定時(shí)長(zhǎng)的任務(wù)時(shí)舞肆,Java就會(huì)收回CPU的執(zhí)行權(quán)焦辅,從而合理應(yīng)用CPU的資源。我們根據(jù)圖可以看出椿胯,線(xiàn)程在阻塞過(guò)程結(jié)束之后筷登,會(huì)重新進(jìn)入就緒狀態(tài),重新?lián)寠ZCPU資源哩盲。這時(shí)候前方,我們可能會(huì)產(chǎn)生一個(gè)疑問(wèn),如何跳出阻塞過(guò)程呢?又以上幾種可能造成線(xiàn)程阻塞的情況來(lái)看廉油,都是存在一個(gè)時(shí)間限制的惠险,當(dāng)sleep()方法的睡眠時(shí)長(zhǎng)過(guò)去后,線(xiàn)程就自動(dòng)跳出了阻塞狀態(tài)抒线,第二種則是在返回了一個(gè)參數(shù)之后班巩,在獲取到了等待的通知時(shí),就自動(dòng)跳出了線(xiàn)程的阻塞過(guò)程

三嘶炭、什么是單線(xiàn)程和多線(xiàn)程抱慌?

單線(xiàn)程,顧名思義即是只有一條線(xiàn)程在執(zhí)行任務(wù)眨猎,這種情況在我們?nèi)粘5墓ぷ鲗W(xué)習(xí)中很少遇到抑进,所以我們只是簡(jiǎn)單做一下了解

多線(xiàn)程,創(chuàng)建多條線(xiàn)程同時(shí)執(zhí)行任務(wù)睡陪,這種方式在我們的日常生活中比較常見(jiàn)寺渗。但是,在多線(xiàn)程的使用過(guò)程中兰迫,還有許多需要我們了解的概念信殊。比如,在理解上并行和并發(fā)的區(qū)別逮矛,以及在實(shí)際應(yīng)用的過(guò)程中多線(xiàn)程的安全問(wèn)題鸡号,對(duì)此,我們需要進(jìn)行詳細(xì)的了解须鼎。

并行和并發(fā):在我們看來(lái)鲸伴,都是可以同時(shí)執(zhí)行多種任務(wù)府蔗,那么,到底他們二者有什么區(qū)別呢汞窗?

并發(fā)姓赤,從宏觀方面來(lái)說(shuō),并發(fā)就是同時(shí)進(jìn)行多種時(shí)間仲吏,實(shí)際上不铆,這幾種時(shí)間,并不是同時(shí)進(jìn)行的裹唆,而是交替進(jìn)行的誓斥,而由于CPU的運(yùn)算速度非常的快,會(huì)造成我們的一種錯(cuò)覺(jué)许帐,就是在同一時(shí)間內(nèi)進(jìn)行了多種事情

而并發(fā)劳坑,則是真正意義上的同時(shí)進(jìn)行多種事情。這種只可以在多核CPU的基礎(chǔ)下完成成畦。

還有就是多線(xiàn)程的安全問(wèn)題距芬?為什么會(huì)造成多線(xiàn)程的安全問(wèn)題呢?我們可以想象一下循帐,如果多個(gè)線(xiàn)程同時(shí)執(zhí)行一個(gè)任務(wù)框仔,name意味著他們共享同一種資源,由于線(xiàn)程CPU的資源不一定可以被誰(shuí)搶占到拄养,這是离斩,第一條線(xiàn)程先搶占到CPU資源,他剛剛進(jìn)行了第一次操作瘪匿,而此時(shí)第二條線(xiàn)程搶占到了CPU的資源捐腿,name,共享資源還來(lái)不及發(fā)生變化柿顶,就同時(shí)有兩條數(shù)據(jù)使用了同一條資源,具體請(qǐng)參考多線(xiàn)程買(mǎi)票問(wèn)題操软。這個(gè)問(wèn)題我們應(yīng)該如何解決那嘁锯?

有造成問(wèn)題的原因我們可以看出,這個(gè)問(wèn)題主要的矛盾在于聂薪,CPU的使用權(quán)搶占和資源的共享發(fā)生了沖突家乘,解決時(shí),我們只需要讓一條線(xiàn)程戰(zhàn)歌了CPU的資源時(shí)藏澳,阻止第二條線(xiàn)程同時(shí)搶占CPU的執(zhí)行權(quán)仁锯,在代碼中,我們只需要在方法中使用同步代碼塊即可翔悠。在這里业崖,同步代碼塊不多進(jìn)行贅述野芒,可以自行了解。

四双炕,線(xiàn)程池

又以上介紹我們可以看出狞悲,在一個(gè)應(yīng)用程序中,我們需要多次使用線(xiàn)程妇斤,也就意味著摇锋,我們需要多次創(chuàng)建并銷(xiāo)毀線(xiàn)程。而創(chuàng)建并銷(xiāo)毀線(xiàn)程的過(guò)程勢(shì)必會(huì)消耗內(nèi)存站超。而在Java中荸恕,內(nèi)存資源是及其寶貴的,所以死相,我們就提出了線(xiàn)程池的概念融求。

線(xiàn)程池:Java中開(kāi)辟出了一種管理線(xiàn)程的概念,這個(gè)概念叫做線(xiàn)程池媳纬,從概念以及應(yīng)用場(chǎng)景中双肤,我們可以看出,線(xiàn)程池的好處钮惠,就是可以方便的管理線(xiàn)程茅糜,也可以減少內(nèi)存的消耗。

那么素挽,我們應(yīng)該如何創(chuàng)建一個(gè)線(xiàn)程池那?Java中已經(jīng)提供了創(chuàng)建線(xiàn)程池的一個(gè)類(lèi):Executor

而我們創(chuàng)建時(shí)蔑赘,一般使用它的子類(lèi):ThreadPoolExecutor.

public?ThreadPoolExecutor(int?corePoolSize,

int?maximumPoolSize,

long?keepAliveTime,

TimeUnit?unit,

BlockingQueueworkQueue,

ThreadFactory?threadFactory,

RejectedExecutionHandler?handler)

這是其中最重要的一個(gè)構(gòu)造方法,這個(gè)方法決定了創(chuàng)建出來(lái)的線(xiàn)程池的各種屬性预明,下面依靠一張圖來(lái)更好的理解線(xiàn)程池和這幾個(gè)參數(shù):

又圖中缩赛,我們可以看出,線(xiàn)程池中的corePoolSize就是線(xiàn)程池中的核心線(xiàn)程數(shù)量撰糠,這幾個(gè)核心線(xiàn)程酥馍,只是在沒(méi)有用的時(shí)候,也不會(huì)被回收阅酪,maximumPoolSize就是線(xiàn)程池中可以容納的最大線(xiàn)程的數(shù)量旨袒,而keepAliveTime,就是線(xiàn)程池中除了核心線(xiàn)程之外的其他的最長(zhǎng)可以保留的時(shí)間术辐,因?yàn)樵诰€(xiàn)程池中砚尽,除了核心線(xiàn)程即使在無(wú)任務(wù)的情況下也不能被清除,其余的都是有存活時(shí)間的辉词,意思就是非核心線(xiàn)程可以保留的最長(zhǎng)的空閑時(shí)間必孤,而util,就是計(jì)算這個(gè)時(shí)間的一個(gè)單位瑞躺,workQueue敷搪,就是等待隊(duì)列兴想,任務(wù)可以?xún)?chǔ)存在任務(wù)隊(duì)列中等待被執(zhí)行,執(zhí)行的是FIFIO原則(先進(jìn)先出)购啄。threadFactory襟企,就是創(chuàng)建線(xiàn)程的線(xiàn)程工廠,最后一個(gè)handler,是一種拒絕策略狮含,我們可以在任務(wù)滿(mǎn)了知乎顽悼,拒絕執(zhí)行某些任務(wù)。

線(xiàn)程池的執(zhí)行流程又是怎樣的呢几迄?

有圖我們可以看出蔚龙,任務(wù)進(jìn)來(lái)時(shí),首先執(zhí)行判斷映胁,判斷核心線(xiàn)程是否處于空閑狀態(tài)木羹,如果不是,核心線(xiàn)程就先就執(zhí)行任務(wù)解孙,如果核心線(xiàn)程已滿(mǎn)坑填,則判斷任務(wù)隊(duì)列是否有地方存放該任務(wù),若果有弛姜,就將任務(wù)保存在任務(wù)隊(duì)列中脐瑰,等待執(zhí)行,如果滿(mǎn)了廷臼,在判斷最大可容納的線(xiàn)程數(shù)苍在,如果沒(méi)有超出這個(gè)數(shù)量,就開(kāi)創(chuàng)非核心線(xiàn)程執(zhí)行任務(wù)荠商,如果超出了寂恬,就調(diào)用handler實(shí)現(xiàn)拒絕策略。

handler的拒絕策略:

有四種:第一種AbortPolicy:不執(zhí)行新任務(wù)莱没,直接拋出異常初肉,提示線(xiàn)程池已滿(mǎn)

第二種DisCardPolicy:不執(zhí)行新任務(wù),也不拋出異常

第三種DisCardOldSetPolicy:將消息隊(duì)列中的第一個(gè)任務(wù)替換為當(dāng)前新進(jìn)來(lái)的任務(wù)執(zhí)行

第四種CallerRunsPolicy:直接調(diào)用execute來(lái)執(zhí)行當(dāng)前任務(wù)

五饰躲,四種常見(jiàn)的線(xiàn)程池:

CachedThreadPool:可緩存的線(xiàn)程池朴译,該線(xiàn)程池中沒(méi)有核心線(xiàn)程,非核心線(xiàn)程的數(shù)量為Integer.max_value属铁,就是無(wú)限大,當(dāng)有需要時(shí)創(chuàng)建線(xiàn)程來(lái)執(zhí)行任務(wù)躬翁,沒(méi)有需要時(shí)回收線(xiàn)程焦蘑,適用于耗時(shí)少,任務(wù)量大的情況盒发。

SecudleThreadPool:周期性執(zhí)行任務(wù)的線(xiàn)程池例嘱,按照某種特定的計(jì)劃執(zhí)行線(xiàn)程中的任務(wù)狡逢,有核心線(xiàn)程,但也有非核心線(xiàn)程拼卵,非核心線(xiàn)程的大小也為無(wú)限大奢浑。適用于執(zhí)行周期性的任務(wù)。

SingleThreadPool:只有一條線(xiàn)程來(lái)執(zhí)行任務(wù)腋腮,適用于有順序的任務(wù)的應(yīng)用場(chǎng)景雀彼。

FixedThreadPool:定長(zhǎng)的線(xiàn)程池,有核心線(xiàn)程即寡,核心線(xiàn)程的即為最大的線(xiàn)程數(shù)量徊哑,沒(méi)有非核心線(xiàn)程

六,線(xiàn)程池

1聪富、配置

@Configuration@EnableAsyncpublicclassTaskPoolConfig{@Bean("taskExecutor")publicExecutortaskExecutro(){? ? ? ? ThreadPoolTaskExecutor taskExecutor =newThreadPoolTaskExecutor();? ? ? ? taskExecutor.setCorePoolSize(10);? ? ? ? taskExecutor.setMaxPoolSize(50);? ? ? ? taskExecutor.setQueueCapacity(200);? ? ? ? taskExecutor.setKeepAliveSeconds(60);? ? ? ? taskExecutor.setThreadNamePrefix("taskExecutor--");? ? ? ? taskExecutor.setWaitForTasksToCompleteOnShutdown(true);? ? ? ? taskExecutor.setAwaitTerminationSeconds(60);returntaskExecutor;? ? }}

2莺丑、使用

@ComponentpublicclassAsyncTask{@Async("taskExecutor")publicvoidtesTask(inti){? ? ? ? System.out.println(Thread.currentThread().getName()+"-----"+i);? ? }@Async("taskExecutor")publicvoidstringTask(String str){? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName()+str);? ? }}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市墩蔓,隨后出現(xiàn)的幾起案子梢莽,更是在濱河造成了極大的恐慌,老刑警劉巖奸披,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昏名,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡源内,警方通過(guò)查閱死者的電腦和手機(jī)葡粒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)膜钓,“玉大人嗽交,你說(shuō)我怎么就攤上這事∷绦保” “怎么了夫壁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)沃疮。 經(jīng)常有香客問(wèn)我盒让,道長(zhǎng),這世上最難降的妖魔是什么司蔬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任邑茄,我火速辦了婚禮,結(jié)果婚禮上俊啼,老公的妹妹穿的比我還像新娘肺缕。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布同木。 她就那樣靜靜地躺著浮梢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彤路。 梳的紋絲不亂的頭發(fā)上秕硝,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音洲尊,去河邊找鬼远豺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛颊郎,可吹牛的內(nèi)容都是我干的憋飞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼姆吭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼榛做!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起内狸,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤检眯,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后昆淡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锰瘸,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年昂灵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了避凝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眨补,死狀恐怖管削,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撑螺,我是刑警寧澤含思,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站甘晤,受9級(jí)特大地震影響含潘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜线婚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一遏弱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塞弊,春花似錦腾窝、人聲如沸缀踪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至奏候,卻和暖如春循集,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔗草。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工咒彤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咒精。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓镶柱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親模叙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子歇拆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348