一文讀懂線程池的工作原理(故事白話文)

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文以程序員做需求的例子,比喻線程池的工作過程。以故事白話的方式展開,跟大家闡述線程池工作原理,以方便大家更好理解線程池,謝謝閱讀哈~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是線程池?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是核心線程?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是阻塞隊列?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是非核心線程?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是空閒存活時間?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是飽和策略?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"線程池工作原理流程圖&源碼概覽"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"github地址,感謝每一顆Star"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://github.com/whx123/JavaHome","title":null},"content":[{"type":"text","text":"github.com/whx123/Java…"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公衆號:"},{"type":"text","marks":[{"type":"strong"}],"text":"Java鬥帝"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是線程池?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"小田螺"},{"type":"text","text":" 勤勤懇懇,任勞任怨,夜以繼日地工作,終於有一天,他晉升爲公司的主管,負責公司日常業務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有一天,老闆找到了小田螺,“我們公司員工越來越多了,我想搞個"},{"type":"text","marks":[{"type":"strong"}],"text":"員工管理系統"},{"type":"text","text":",你那邊安排一下哈,要在一個月後完成。” 小田螺拍拍胸口沒問題!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲當前公司還沒有程序員,所以小田螺快馬加鞭打開"},{"type":"text","marks":[{"type":"strong"}],"text":"豬八戒網"},{"type":"text","text":",提交員工管理系統需求,等待不久,"},{"type":"text","marks":[{"type":"strong"}],"text":"開發者(名字,線程A)"},{"type":"text","text":" 接單,談好合同,開始開發,系統交付...一系列流程並且一個月過後,一個五臟俱全的員工管理系統終於完成了...老闆對此大加讚賞~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"過了不久,老闆再次發話,“公司越來越多人遲到了,我們再搞個"},{"type":"text","marks":[{"type":"strong"}],"text":"考勤系統"},{"type":"text","text":"吧!\"小田螺接到任務,馬上又開始上豬八戒網,提需求找人開發,這次來了"},{"type":"text","marks":[{"type":"strong"}],"text":"線程B接單"},{"type":"text","text":"......"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"逝者如斯,月底了,老闆又提出開發個薪酬系統需求...小田螺聽了頭皮發麻,one day day的,重複去網上找人開發!“爲了節省成本,不如我們僱傭幾個程序員(線程a,b,c),成立自己的IT技術部門吧!我們就管IT部門叫"},{"type":"text","marks":[{"type":"strong"}],"text":"線程池"},{"type":"text","text":"吧!”老闆聽了,一拍即合!!!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"線程池就是管理線程的池子,當有任務要處理時,不用頻繁創建新線程,而是從池子拿個線程出來處理。當任務執行完,線程並不會被銷燬,而是在等待下一個任務。因此可以節省資源,提高響應速度。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是核心線程?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"線程池"},{"type":"text","text":"IT部門成立後,僱傭了幾個與公司有正式合同關係的員工a,b,c,"},{"type":"text","marks":[{"type":"strong"}],"text":"小田螺"},{"type":"text","text":"管他們幾個正式員工做"},{"type":"text","marks":[{"type":"strong"}],"text":"核心線程"},{"type":"text","text":"。當老闆提一個需求過來,小田螺就把需求分配給"},{"type":"text","marks":[{"type":"strong"}],"text":"手上沒活幹"},{"type":"text","text":"的線程處理..."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是阻塞隊列?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一天早上,老闆睡眼惺忪。來到公司後,一口氣提了"},{"type":"text","marks":[{"type":"strong"}],"text":"四個需求"},{"type":"text","text":",a,b,c 按順領完任務後,發現還剩餘一個需求任務。這個怎麼安排呢?難道又去"},{"type":"text","marks":[{"type":"strong"}],"text":"豬八戒兼職網"},{"type":"text","text":"找人嘛?成立了"},{"type":"text","marks":[{"type":"strong"}],"text":"線程池IT部門"},{"type":"text","text":",還去找人(線程幹活),會被人笑落大牙的!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"聰明的小田螺想到一個好辦法,我們可以搞個DPMS需求池,把還沒分配的需求,放進待完成的DPMS需求池裏面吧,等到a,b,c誰先幹完活,再把這個任務領走。這個DPMS需求池,我們給它取名"},{"type":"text","marks":[{"type":"strong"}],"text":"阻塞隊列"},{"type":"text","text":",英文名叫"},{"type":"text","marks":[{"type":"strong"}],"text":"WorkQueue"},{"type":"text","text":"吧!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是非核心線程?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"又在一個晴空萬里的午後,老闆喝了一杯咖啡,閒來沒事,就跑去"},{"type":"text","marks":[{"type":"strong"}],"text":"阻塞隊列"},{"type":"text","text":"(DPMS需求池)看看,一看就傻帽了!!需求池堆積了幾十個需求,排期都是滿滿的了。老闆馬上叫"},{"type":"text","marks":[{"type":"strong"}],"text":"小田螺進來辦公室"},{"type":"text","text":",以商量如何處理這些需求任務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“要不,我們僱傭多幾個員工(搞多幾個"},{"type":"text","marks":[{"type":"strong"}],"text":"核心線程"},{"type":"text","text":")?” “不行不行,公司財務"},{"type":"text","marks":[{"type":"strong"}],"text":"開銷"},{"type":"text","text":"有點大!”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“要不然,我們要求業務提少點任務需求?("},{"type":"text","marks":[{"type":"strong"}],"text":"請求少點"},{"type":"text","text":")” “你是不是傻,請求少點,不是自斷財路嘛?你回家想想辦法先吧!!”老闆放大了他的嗓門~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"小田螺回家閉目讓神,每天早早就睡覺,兩耳不聞窗外事...終於有一天,在一個夢香裏,他想到了一個好辦法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“老闆,我們可以去別的公司("},{"type":"text","marks":[{"type":"strong"}],"text":"外包公司"},{"type":"text","text":")僱傭幾個員工(假設名字爲d,e,f,g)一段時間,讓它們來做"},{"type":"text","marks":[{"type":"strong"}],"text":"DPMS需求池(阻塞隊列)"},{"type":"text","text":" 裏面的需求。等到做完需求,再派他們回去就好啦。” 老闆一聽就樂了,這個方案好,心裏美滋滋:"},{"type":"text","marks":[{"type":"strong"}],"text":"需求的活有人幹了,公司財務又省錢,兩全其美呀"},{"type":"text","text":"~ 這幾個派遣來的外包員工(d,e,f,g),我們就把它叫做"},{"type":"text","marks":[{"type":"strong"}],"text":"非核心線程"},{"type":"text","text":"吧。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是空閒時間?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自從來了d,e,f,g外包員工("},{"type":"text","marks":[{"type":"strong"}],"text":"非核心線程"},{"type":"text","text":"),老闆長舒一口氣,這麼多活,終於有人幹了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是呢,又有一天,到了7點所謂的下班時間,老闆走出辦公室,發現"},{"type":"text","marks":[{"type":"strong"}],"text":"線程池"},{"type":"text","text":"IT部門的員工,都走得七七八八了。心裏一怒:"},{"type":"text","marks":[{"type":"strong"}],"text":"這幫粉腸,怎麼一到下班時間就跑,工作這麼不飽和了"},{"type":"text","text":"?他隨手點進DPMS需求池,才發現,原來需求都被做完了。。。還有一堆外包同事(非核心線程)要發工資呢,這波虧大了~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二天,小田螺被"},{"type":"text","marks":[{"type":"strong"}],"text":"祕密"},{"type":"text","text":"叫進了老闆辦公室,既然DPMS需求池都已經沒需求了。我們準備派外包同事(非核心線程)回去吧?但是呢一般,需求一沒有,就馬上讓他們回去("},{"type":"text","marks":[{"type":"strong"}],"text":"線程回收"},{"type":"text","text":"),如果需求一下子又來,就有點hold不住了..."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“要不醬紫,我們等需求池空的時候,隔個15天還是10天,再讓外包同事("},{"type":"text","marks":[{"type":"strong"}],"text":"非核心線程"},{"type":"text","text":")回去吧?” 這個定義的15天或者10天,就是"},{"type":"text","marks":[{"type":"strong"}],"text":"線程空閒存活時間"},{"type":"text","text":"啦"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"什麼是飽和策略?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在臨近雙11的時候,不僅老闆提了良多需求,新來的運營小姐姐們,也提了好多好多的需求。新需求如源頭活水,滾滾的來~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先呢,"},{"type":"text","marks":[{"type":"strong"}],"text":"線程池"},{"type":"text","text":"IT部門a,b,c三個正式員工(核心線程)都忙於處理需求("},{"type":"text","marks":[{"type":"strong"}],"text":"請求"},{"type":"text","text":"),接着,DPMS需求池("},{"type":"text","marks":[{"type":"strong"}],"text":"阻塞隊列"},{"type":"text","text":")也被擠滿了,最後呢,連d,e,f,g外包同事("},{"type":"text","marks":[{"type":"strong"}],"text":"非核心線程"},{"type":"text","text":")也忙得不可開交。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這時候,需求還是做不完,怎麼辦呢?雙11趕着上線呢?小田螺愁眉苦臉,從"},{"type":"text","marks":[{"type":"strong"}],"text":"潮起愁到潮落"},{"type":"text","text":"..."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒辦法了,只能動用"},{"type":"text","marks":[{"type":"strong"}],"text":"飽和策略"},{"type":"text","text":"啦。比如"},{"type":"text","marks":[{"type":"strong"}],"text":"丟棄需求任務"},{"type":"text","text":"?"},{"type":"text","marks":[{"type":"strong"}],"text":"拋異常,告訴老闆別加需求了"},{"type":"text","text":"?"},{"type":"text","marks":[{"type":"strong"}],"text":"丟棄需求池最老的需求任務"},{"type":"text","text":"?還是"},{"type":"text","marks":[{"type":"strong"}],"text":"交給提需求的人自己處理"},{"type":"text","text":"?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後老闆決定,"},{"type":"text","marks":[{"type":"strong"}],"text":"拒絕再提新的需求"},{"type":"text","text":",於是"},{"type":"text","marks":[{"type":"strong"}],"text":"線程池"},{"type":"text","text":"IT部門還是正常運行~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"線城池的飽和策略事件,主要有四種類型"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"AbortPolicy(拋出一個異常,默認的)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DiscardPolicy(新提交的任務直接被拋棄)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DiscardOldestPolicy(丟棄隊列裏最老的任務,將當前這個任務繼續提交給線程池)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CallerRunsPolicy(交給線程池調用所在的線程進行處理,即將某些任務回退到調用者)"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"線程池工作原理流程圖 & 源碼概覽"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"故事講完啦,再複習下線程池工作流程圖吧~"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1b/1bb61e8a4074510f9ffd6ac3d9546b78.png","alt":"","title":"","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有興趣的朋友,源碼也看下吧~"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":" if (command == null)\n throw new NullPointerException();\n int c = ctl.get();\n //判斷當前活躍線程數是否小於corePoolSize\n if (workerCountOf(c) < corePoolSize) {\n //如果小於,則調用addWorker創建線程執行任務\n if (addWorker(command, true))\n return;\n c = ctl.get();\n }\n //如果大於等於corePoolSize,則將任務添加到workQueue隊列。\n if (isRunning(c) && workQueue.offer(command)) {\n int recheck = ctl.get();\n if (! isRunning(recheck) && remove(command))\n reject(command);\n else if (workerCountOf(recheck) == 0)\n addWorker(null, false);\n }\n //如果放入workQueue隊列失敗,則創建非核心線程執行任務 \n else if (!addWorker(command, false))\n //(如果這時創建線程失敗(當前線程數大於等於maximumPoolSize時))\n 調用reject拒絕接受任務\n reject(command);"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"公衆號"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"歡迎關注公衆號:【Java鬥帝】"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"歡迎大家關注,持續推出乾貨~"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"後臺回覆666,領取私人整理的1000道互聯網面試題"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章