天天看點

深層次揭示runBlocking與coroutineScope之間的異同點

在之前https://www.cnblogs.com/webor2006/p/11731763.html咱們寫過這樣的一個例子,先來回顧一下:

深層次揭示runBlocking與coroutineScope之間的異同點

也就是來示範runBlocking與coroutineScope之間的異同點,當時還闡述了一個對它的理論描述,也來回顧一下:

深層次揭示runBlocking與coroutineScope之間的異同點

這裡再開個篇幅來提出的原因是在于。。這裡面有一些深層次的東東需要再次挖掘,而問題的焦點是在:

深層次揭示runBlocking與coroutineScope之間的異同點

回到代碼根據這段文字的了解照理應該是這樣的嘛:

深層次揭示runBlocking與coroutineScope之間的異同點

結果肯定不是我們現在所質疑的觀點啦,是以這也是需要再單獨拎出來值得探讨的東東,這是因為關于runBlocking和coroutineScope是有更加深層的原因的,下面先來闡述一下:

1、runBlocking并非挂起函數;也就是說,調用它的線程會一直位于該函數中,直到協程執行完畢為止。

2、coroutineScope是挂起函數;也就是說,如果其中的協程挂起,那麼coroutineScope函數也會挂起。這樣,建立coroutineScope的外層函數就可以繼續在同一個線程中執行了,該線程會【逃離】coroutineScope之外,并且可以做其他一些事情。

咱們來看一下runBlocking函數的定義:

深層次揭示runBlocking與coroutineScope之間的異同點

再來看一下coroutineScope函數的定義:

深層次揭示runBlocking與coroutineScope之間的異同點

說實話對于上面的理論描述有點難以了解,怎麼最終的welcome的輸出是在最後列印的而非咱們預期了解的要立馬列印出來,其實需要這樣來了解:

深層次揭示runBlocking與coroutineScope之間的異同點

是以很明顯“welcome”肯定是最後才會被列印出來的,但是!!!貌似上面的有點像是coroutineScope函數阻塞了目前線程,這個觀點又與這個理論貌似沖突了呀:

深層次揭示runBlocking與coroutineScope之間的異同點

其實這個理論是沒任何問題的,就是了解上需要這樣來了解,如下:

深層次揭示runBlocking與coroutineScope之間的異同點

如果說coroutineScope是阻塞了目前線程,也就不可能能執行到這句代碼:

深層次揭示runBlocking與coroutineScope之間的異同點
深層次揭示runBlocking與coroutineScope之間的異同點

是以這也能論證coroutineScope确實是不會阻塞目前線程的,而當跳出到runBlocing代碼時,它裡面會有一個事件循環:

深層次揭示runBlocking與coroutineScope之間的異同點

當事件發生時則就會觸發事件,也就類似于當休眠完之後就要開始列印語句了,也就相當于事件觸發了,如下:

深層次揭示runBlocking與coroutineScope之間的異同點

這也就是為啥這句話能列印出來的原因,也就是說,其coroutinScope的真正流程是它會将排程傳回給外層runBlocking裡面的代碼,而且是coroutineScope之上的代碼,而非之下的代碼,而welcome為啥是最後才列印的真正原因絕對不是因為coroutinScope将線程的代碼給阻塞了,這一點确實是比較難了解!!

好,下面了解了這些深層次的理論之後,咱們再以更加正确的姿勢來解讀一下整個程式的執行流程:

深層次揭示runBlocking與coroutineScope之間的異同點
深層次揭示runBlocking與coroutineScope之間的異同點

接下來線程就會碰到coroutineScope挂起函數了:

深層次揭示runBlocking與coroutineScope之間的異同點

當遇到挂起函數時,就需要立馬來區分它之上的代碼和之下的代碼,記住一點它之下的代碼一定是需要等待coroutineScope中的協程代碼整個執行完了才能被執行到【如果這個先提觀點不知道那整個流程就确實是比較難解釋了,這個一定得要有這種概念】,而:

深層次揭示runBlocking與coroutineScope之間的異同點

另外一點是當線程遇到了挂起函數會立馬從它往上傳回,也就是傳回到這塊代碼:

深層次揭示runBlocking與coroutineScope之間的異同點
深層次揭示runBlocking與coroutineScope之間的異同點

接下來由于延時到了,接着coroutineScope中的這段代碼會得到執行:

深層次揭示runBlocking與coroutineScope之間的異同點
深層次揭示runBlocking與coroutineScope之間的異同點

接着10s過後,裡面的協程這塊代碼就會被列印了:

深層次揭示runBlocking與coroutineScope之間的異同點
深層次揭示runBlocking與coroutineScope之間的異同點

當這個列印完成,則整個coroutineScope中的協程都執行完了,那該挂起函數也就可以退出了,最後就可以執行挂起函數之下的代碼,也就是:

深層次揭示runBlocking與coroutineScope之間的異同點

是以:

深層次揭示runBlocking與coroutineScope之間的異同點

至此!!整個流程就再次以一個全新的視角分析完了~~ 雖說是比較細節,但是對于整個協程的認知了解是非常之重要的!!