如下文章來源於編程技術宇宙 ,做者軒轅之風O編程
「久聞Java語言跨越平臺,框架衆多,不過二十年功夫,就已晉升天下第一編程語言,今日一見,果真名不虛傳吶!」併發
「使者先生您過獎了,我們快些走,國王陛下已經等候多時了」框架
今日,Java帝國朝堂之上迎來了一位神祕的來賓。
異步
來到大殿之上,只見國王正襟危坐,閉目養神,不怒自威,堂下羣臣鹹集,紛紛側目。編程語言
「來者何人?」,國王一旁的內侍問到。函數
「我乃GoLang帝國使者——Goroutine」,使者答道。
「GoLang帝國?何方番邦小國?寡人竟從未聽聞」,國王閉眼說到。高併發
說罷,羣臣皆笑了起來。spa
「來此所爲什麼事?」,內侍繼續問到。操作系統
使者回答:「我此行特爲傳道而來」線程
說完,國王睜開了眼睛,「傳道?我Java帝國乃天下第一編程帝國,只有咱們傳出去,哪有學別人之道?」
使者不卑不亢,說到:「Java帝國雖如日中天,但卻有一處缺陷,假以時日,必成大患」
「哦,你卻是說說看,如若言語不通,即刻轟出殿去。」,國王厲聲喝到。
「敢問陛下,Java線程執行到阻塞函數時,該當如何?」,使者問到。
一旁的線程大臣見狀,上前說到:「遇到阻塞那天然要被操做系統掛起,切換到別的線程」
「敢問大人,線程切換是否須要成本?若是大量線程頻繁切換,成本又當如何?」,使者追問到。
「你若關心這個問題,那就不用阻塞函數,經過異步回調來進行」,線程大臣答道。
使者嘴角上揚,微微一笑,「好一個異步回調!異步回調確實不用阻塞,不過它有兩宗罪,其一:割裂了原來的代碼業務邏輯,其二:陷入回調地獄難以維護」
「這也不行,那也不行,你這人還真難伺候」,線程大臣有些急了。
使者轉身面向國王說到:「啓稟陛下,我有一法,可以讓線程遇到阻塞函數後不需切換線程,也不用異步回調還能夠繼續運行下去,是高併發開發神技」
國王一聽來了興趣:「哦,還有這種事?說來聽聽」
使者拜了一拜,說到:「線程能夠在遇到阻塞的地方後,保存執行的上下文,轉而去執行別處的代碼。待阻塞的請求完成後,再轉而回去繼續執行」
國王不解,問到:「什麼叫轉而去執行別處的代碼?什麼叫回去繼續執行?這函數執行到一半還能中途退出再回來?」
「是的,沒錯!」,使者回答。
此話一出,朝堂上議論紛紛,羣臣都露出了鄙夷的笑容。
「簡直荒謬!函數執行從進入到return退出,歷來都是一鼓作氣,哪有中途執行一半退出,再回來接着執行的道理?簡直聞所未聞!」,一旁的線程大臣說到。
使者繼續說到:「一鼓作氣?恐怕不是吧?線程執行函數中途,遇到時間片用完或者遇到I/O阻塞,就會被操做系統保存上下文後掛起,切換到其餘線程。然後等到機會再回過頭繼續執行,不是嗎?」
線程大臣怒斥道:「強詞奪理!你說的這狀況是操做系統在調度管理多個線程,對我們的應用層線程來講都是透明的,無需關心」
使者沒有退讓,卻問道:「既然操做系統能夠調度管理多個線程,那爲什麼線程不能夠調度管理函數的執行?」
羣臣再次交頭接耳,議論起來。
「陛下,此番邦使者妖言惑衆,微臣建議即刻逐出大殿,以正視聽!」
國王應允,隨即遣人上前。
不待侍衛上前,使者自行離去,邊走邊說到:「可嘆!堂堂Java帝國,卻容不下一個新技術」
使者心灰意冷,打算離開Java帝國,卻在半道上被人給攔了下來。
「先生請留步,我家主人請先生府上相會」
使者來到府上,原來主人乃當地一富豪鄉紳。
「先生今日在朝堂之事,我已據說,在下對先生提到的函數執行過程當中可中斷和恢復的技術很有興趣,還請先生不吝賜教」,主人說完拜了一拜。
「賜教不敢當,我這次來Java帝國,所傳之道名叫協程,是一種高併發開發的絕技,可無奈貴國國君與大臣皆不識貨,無功而返,惋惜啊,惋惜!」,使者嘆息到。
「協程?這是何物?我只據說過進程和線程,倒是從未聽過協程」
使者起身說到:「線程是操做系統抽象出來的執行流,由操做系通通一調度管理。那在一個線程中,一樣能夠抽象出多個執行流,由線程來統一調度管理。這線程之上抽象的執行流就是協程」
主人有些不解,問到:「一個線程怎麼會有多個執行流呢?」
「這即是我今日在朝堂上說的,線程執行函數遇到阻塞後,能夠保存上下文後退出,轉而執行別處的代碼,這裏就從一個執行流轉向了另外的執行流」,使者解釋到。
主人拍案而起,「原來是這個意思,妙哉,妙哉啊!不過,這線程是操做系統在調度管理,那線程裏抽象出來的執行流,也就是協程,該怎麼調度管理呢?操做系統能夠經過時鐘中斷和系統調用進入內核來剝奪線程的執行權,那線程該如何剝奪協程的執行權來實現調度管理呢?」
「真是個好問題!線程的調度由操做系統來管理,是搶佔式調度。而協程不一樣,協程須要互相配合,主動交出執行權,這也是協程的名字——協做式程序的來歷」
「主動交出執行權?如何辦到?」,主人追問。
「辦法有不少,好比C++帝國有一協程框架,名叫libco,他經過HOOK關鍵的系統函數來實現調度器的介入」
「那大家Golang是怎麼作的?也是這樣嗎?」
「咱們Golang帝國可不同,咱們先天設計就是支持協程,系統調用都被咱們封裝好了,應用程序調用時遇到須要阻塞的,像是文件讀寫Read/Write、Sleep咱們的調度器就能有機會介入,去執行調度管理了」,使者得意的說到
主人思考片刻,問到:「那咱們Java該如何實現呢,還請先生賜教」
「大家Java語言,是經過JVM在執行,字節碼的執行都在JVM的掌控之中,要想實現對應用代碼執行流的中斷和恢復還不是易如反掌?」,使者說到。
主人點了點頭,如有所思。
主人與使者交談甚歡,不知不覺已近黃昏。
主人起身說到:「今蒙先生賜教,大慰生平。還請先生在府上多留時日,我好細細請教。」
使者連連揮手,說到:「我還有要事在身,明日就要離去」
「不知先生欲往何處?」
「據說C++帝國又要發佈新版本,我打算前往傳道」
主人面露疑惑:「C++帝國不是有libco了嗎?」
「libco終究不是朝廷之物,此番前去,但願可讓協程歸入新的官方標準」
翌日清晨,使者拜別主人,策馬離去。
不久,Java帝國朝堂上傳來消息,民間有人推出了協程框架——Quasar,一時朝野震動。