再來說一說線程池

? ? ? ?這段時間一直在忙著自己的事情腊脱,搞的非常尷尬访得,一直沒能靜下心來好好想想。不過還好陕凹,最近對于線程池的東西還是一直處于進步階段悍抑。

? ? ? ? 我還是習慣直接動嘴說說,以后萬一想開了杜耙,也會貼很多源碼上來搜骡,但是現(xiàn)在主要還是想打字來解釋,畢竟源碼很多時候來的更清晰佑女,但是我這樣寫的目的也是等于加強自己的記憶记靡,所以先不用源碼來增加篇幅了谈竿。

? ? ? ? 還是先new一個線程池開始吧。new ThreadPoolExecutor(0摸吠,0,0空凸,null,new SynchronousQueue<Runnable>());0和null是我上一篇已經(jīng)詳細說的東西了蜕便,現(xiàn)在實在是懶得給他多一點賦值的心情了劫恒。對,沒錯轿腺,我是打算說一下最后這個隊列的两嘴。

? ? ? ? 這個隊列,目前最常見的有三種(ArrayBlockingQueue族壳,LinkedBlockingQueue憔辫,SynchronousQueue),在使用executors創(chuàng)建的線程池中仿荆,你會發(fā)現(xiàn)沒有第一種贰您,具體原因不得而知,可能是:一拢操、限制的太死锦亦?因為array對列是固定緩存池大小的(因為沒人會問這個隊列是干嘛的了吧,好吧令境,我說一句杠园,這個是用來緩存任務的,只有當任務填滿緩存了舔庶,才會用到maxinumpoolsize抛蚁,上一篇。惕橙。瞧甩。)。這種固定死的方式會導致很多意想不到的拒絕(線程池對任務的拒絕措施弥鹦,一般都是默認的----拋異常拒絕)肚逸。而且我感覺推薦使用executors也是有一種不在拒絕的味道(個人主觀臆斷,沒什么依據(jù)惶凝,主要是從創(chuàng)建的幾種線程池的內(nèi)容中推斷的吼虎,畢竟我只是一個渣渣,后面我會說一點點推理的依據(jù))苍鲜。二、設計不好(求不打臉玷犹,我這個瞎說的)混滔,看過源碼的童鞋應該發(fā)現(xiàn)了洒疚,array隊列的里面只用一把鎖final修飾的。這樣這個隊列在添加和移除的時候都是同一把鎖坯屿,也就是不能出現(xiàn)添加和移除的并發(fā)操作油湖,我大致百度了一下,沒有找到合理的解釋领跛。這樣可能會在線程池頻繁添加和移除的時候出現(xiàn)性能問題乏德。當然這個是我瞎說的,不注意作為依據(jù)吠昭。

? ? ? ? 那我們再來談談剩下的兩個queue吧喊括。linkedBlockingQueue,一看名字就知道矢棚,這個是鏈表的隊列嘛郑什,對,就是這樣的蒲肋,那有什么說的呢蘑拯?首先說一下鎖的問題,這個隊列就很理智(233)的使用了兩個final的lock(take和put)兜粘,對嘛申窘,進出分開嘛,當年我在化工廠里面看設計圖的時候孔轴,就看到人家設計師說剃法,人流物流進進出出嚴格分開滴,沒錯距糖,程序就是要反應現(xiàn)實的玄窝,不然寫程序不就找不到使用的價值了(繼續(xù)瞎說)。然后再來一點不瞎說的悍引。既然是鏈表恩脂,我們存取是不是可以使用雙向鏈表尾放頭取呢?可以趣斤,沒錯俩块,人家就是這么玩的,是不是一點都不意外浓领,你能想到的這么簡單的東西玉凯,人家大牛早就實現(xiàn)了。那么联贩,這樣是不是就有一個很熟悉的生產(chǎn)者消費者模式出現(xiàn)了漫仆,哇塞,如果你能想到這里泪幌,那么和我這個渣渣同一水準了呢(2333)盲厌,反正寫東西的時候署照,瞎想一下,萬一和大神想到一起去了呢吗浩。對建芙,這里就是這樣的。通過前面的兩把鎖(顯示鎖aqs實現(xiàn)的ReentrantLock懂扼,我打算下一次寫一下這個)禁荸,獲取condition(用來休息的),然后每次存/取的時候阀湿,檢查一下容量赶熟,如果滿/虧,那么就休息一下炕倘。至于為什么是循環(huán)钧大,那是因為這里有并發(fā),每次醒來的時候罩旋,先循環(huán)一下啊央,能不能拿到,拿不到就繼續(xù)休息涨醋。如果拿到了瓜饥,就去干活吧。take和put最后一行代碼是叫醒對應的線程浴骂,這個是因為這個線程已經(jīng)拿走了一個乓土,所以讓等著的put填進來。(這里我專門提一下的原因是我第一次就看錯了溯警,搞了半天才發(fā)現(xiàn)是自己atomicInteger的方法getAndDecrement搞錯了---拿到舊值(我理解成了拿到增加之后的值了))趣苏,所以這里我專門提示一下。然后這個隊列就沒有太多可以說的了梯轻,而且實現(xiàn)也很簡單食磕,看一遍源碼就知道了。

? ? ? ? 剩下一個是SynchronousQueue喳挑,這個沒有加blocking彬伦,是不是以為就不是阻塞的呢?這個隊列很特殊伊诵,它是一個轉(zhuǎn)移隊列单绑,自己不保存東西,也就是容量是0,曹宴。那他怎么玩的呢搂橙?首先通過內(nèi)部transfer對象來實現(xiàn)(queue公平,stack非公平)隊列笛坦。說好的不保存東西的呢份氧,是的唯袄,任務過來了弯屈,它是不會保存的蜗帜。那么他保存的是什么呢,沒錯资厉,是空閑的線程厅缺。這個隊列通過put的東西會一直阻塞自己,只有當下一個線程過來take之后才會繼續(xù)自己的邏輯宴偿。所以當新任務來的時候湘捎,這個隊列直接創(chuàng)建新的線程去執(zhí)行,自己不緩存任務窄刘。而當空閑線程回來的時候窥妇,那就可以進隊了,因為put就是await當前線程的娩践,這個是通過lockResource也就是底層native方法的wait活翩,因為這個隊列沒有使用aqs,直接是使用的cas算法翻伺,代碼那叫一個復雜呀材泄。不過慢慢也能看懂,就是node的進出隊列吨岭。算是一個優(yōu)化鎖的實現(xiàn)拉宗,先自旋一會然后等待(根據(jù)cpu數(shù)定次數(shù),如果單cpu辣辫,就不要自旋了旦事,直接wait吧,其他的就是需要的)急灭,這個設計就非常合理姐浮,因為單cpu如果大量的自旋,會明顯拖慢其他的線程化戳。至于這個隊列的公平模式和非公平模式单料,我就不細說了,感覺和鎖的機制差不多点楼,只是他使用了兩種數(shù)據(jù)結(jié)構(gòu)罷了扫尖。

? ? ? ? 說了這么多廢話,現(xiàn)在再說一下java的推薦的幾種選擇掠廓,單線程和固定容量的線程都是選擇的是LinkedBlockingQueue换怖,沒有大小上限,默認是integer.MAX_VALUE(當然可以設置大小的)蟀瞧,前面我說的不建議使用拒絕措施就是這里看到的沉颂,因為如果核心池和最大池固定了条摸,就不再固定緩存的數(shù)量了,這樣在正常的情況就不會有什么拒絕的機會了铸屉。至于cached的線程池钉蒲,那還用說,雖然沒有核心線程彻坛,但是我們最大線程多呀顷啼,也是integer.MAX_VALUE(其實線程池沒有這么大的容量,因為線程池容量和狀態(tài)是一個integer昌屉,32位钙蒙,高位3個位置保存status,低位29個位置保存容量间驮,這種設計躬厌,省了一個atmicinteger的對象,但是對于我這種渣渣竞帽,看起源碼來扛施,苦的一批),所以抢呆,這個緩存池也沒有機會拒絕煮嫌,對了,差點忘記說了抱虐,這個隊列使用的就是SynchronousQueue昌阿,每次過來任務也不緩存了,直接創(chuàng)建新線程就可以了恳邀,反正我們線程多懦冰,用來了過期時間到了也自動銷毀了。不過這種方法其實不是很好谣沸,因為對于任務時間長的任務刷钢,會出現(xiàn)大量的運行和就緒的線程,導致其他的線程運行速度受限乳附,所以最好使用這個線程池的時候内地,執(zhí)行的都是小任務。

? ? ? ? 好了赋除,線程池就到這里吧阱缓,其實很多線程池的東西可以寫,但是寫起來真的沒完沒了了举农,比如每一個線程的創(chuàng)建都是一個work荆针,work不單單實現(xiàn)了runnable接口,還繼承了aqs,沒錯航背,每一個任務本身就是一把鎖喉悴,而且是排他鎖。好了玖媚,大致就這么多了箕肃,下一篇,我們聊聊鎖吧最盅。


? ??????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末突雪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涡贱,更是在濱河造成了極大的恐慌,老刑警劉巖惹想,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件问词,死亡現(xiàn)場離奇詭異,居然都是意外死亡嘀粱,警方通過查閱死者的電腦和手機激挪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锋叨,“玉大人垄分,你說我怎么就攤上這事⊥藁牵” “怎么了薄湿?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長偷卧。 經(jīng)常有香客問我豺瘤,道長,這世上最難降的妖魔是什么听诸? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任坐求,我火速辦了婚禮,結(jié)果婚禮上晌梨,老公的妹妹穿的比我還像新娘桥嗤。我一直安慰自己,他們只是感情好仔蝌,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布泛领。 她就那樣靜靜地躺著,像睡著了一般掌逛。 火紅的嫁衣襯著肌膚如雪师逸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音篓像,去河邊找鬼动知。 笑死,一個胖子當著我的面吹牛员辩,可吹牛的內(nèi)容都是我干的盒粮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼奠滑,長吁一口氣:“原來是場噩夢啊……” “哼丹皱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宋税,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤摊崭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后杰赛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呢簸,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年乏屯,在試婚紗的時候發(fā)現(xiàn)自己被綠了根时。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡辰晕,死狀恐怖蛤迎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情含友,我是刑警寧澤替裆,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站唱较,受9級特大地震影響扎唾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜南缓,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一胸遇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汉形,春花似錦纸镊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岔冀,卻和暖如春凯旭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工罐呼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鞠柄,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓嫉柴,卻偏偏與公主長得像厌杜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子计螺,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容