協(xié)程(3)-到底什么是「非阻塞式」掛起?協(xié)程真的更輕量級嗎?

什么是「非阻塞式掛起」

非阻塞式是相對阻塞式而言的。

編程語言中的很多概念其實都來源于生活,就像脫口秀的段子一樣。

線程阻塞很好理解,現(xiàn)實中的例子就是交通堵塞,它的核心有 3 點:

  • 前面有障礙物,你過不去(線程卡了)
  • 需要等障礙物清除后才能過去(耗時任務結束)
  • 除非你繞道而行(切到別的線程)

從語義上理解「非阻塞式掛起」,講的是「非阻塞式」這個是掛起的一個特點,也就是說,協(xié)程的掛起,就是非阻塞式的,協(xié)程是不講「阻塞式的掛起」的概念的。

我們講「非阻塞式掛起」,其實它有幾個前提:并沒有限定在一個線程里說這件事,因為掛起這件事,本來就是涉及到多線程。

就像視頻里講的,阻塞不阻塞,都是針對單線程講的,一旦切了線程,肯定是非阻塞的,你都跑到別的線程了,之前的線程就自由了,可以繼續(xù)做別的事情了。

所以「非阻塞式掛起」,其實就是在講協(xié)程在掛起的同時切線程這件事情。

為什么要講非阻塞式掛起

既然第三篇說的「非阻塞式掛起」和第二篇的「掛起要切線程」是同一件事情,那還有講的必要嗎?

是有的。因為它在寫法上和單線程的阻塞式是一樣的。

協(xié)程只是在寫法上「看起來阻塞」,其實是「非阻塞」的,因為在協(xié)程里面它做了很多工作,其中有一個就是幫我們切線程。

第二篇講掛起,重點是說切線程先切過去,然后再切回來。

第三篇講非阻塞式,重點是說線程雖然會切,但寫法上和普通的單線程差不多。

讓我們來看看下面的例子:

???
main {
    GlobalScope.launch(Dispatchers.Main) {
        // ?? 耗時操作
        val user = suspendingRequestUser()
        updateView(user)
    }
    
    private suspend fun suspendingRequestUser() : User = withContext(Dispatchers.IO) {
        api.requestUser()
    }
}

從上面的例子可以看到,耗時操作和更新 UI 的邏輯像寫單線程一樣放在了一起,只是在外面包了一層協(xié)程。

而正是這個協(xié)程解決了原來我們單線程寫法會卡線程這件事。

阻塞的本質

首先,所有的代碼本質上都是阻塞式的,而只有比較耗時的代碼才會導致人類可感知的等待,比如在主線程上做一個耗時 50 ms 的操作會導致界面卡掉幾幀,這種是我們?nèi)搜勰苡^察出來的,而這就是我們通常意義所說的「阻塞」。

舉個例子,當你開發(fā)的 app 在性能好的手機上很流暢,在性能差的老手機上會卡頓,就是在說同一行代碼執(zhí)行的時間不一樣。

視頻中講了一個網(wǎng)絡 IO 的例子,IO 阻塞更多是反映在「等」這件事情上,它的性能瓶頸是和網(wǎng)絡的數(shù)據(jù)交換,你切多少個線程都沒用,該花的時間一點都少不了。

而這跟協(xié)程半毛錢關系沒有,切線程解決不了的事情,協(xié)程也解決不了。

協(xié)程與線程

協(xié)程我們講了 3 期,Kotlin 協(xié)程和線程是無法脫離開講的。

別的語言我不說,在 Kotlin 里,協(xié)程就是基于線程來實現(xiàn)的一種更上層的工具 API,類似于 Java 自帶的 Executor 系列 API 或者 Android 的 Handler 系列 API。

只不過呢,協(xié)程它不僅提供了方便的 API,在設計思想上是一個基于線程的上層框架,你可以理解為新造了一些概念用來幫助你更好地使用這些 API,僅此而已。

就像 ReactiveX 一樣,為了讓你更好地使用各種操作符 API,新造了 Observable 等概念。

說到這里,Kotlin 協(xié)程的三大疑問:協(xié)程是什么、掛起是什么、掛起的非阻塞式是怎么回事,就已經(jīng)全部講完了。非常簡單:

協(xié)程就是切線程;
掛起就是可以自動切回來的切線程;
掛起的非阻塞式指的是它能用看起來阻塞的代碼寫出非阻塞的操作,就這么簡單。
當然了,這幾句是總結,它們背后的原理你是一定要掌握住的。如果忘了,再去把之前的視頻和文章看一遍就好。

視頻中還糾正了官方文檔里面的一個錯誤,這里就不再重復了,最后想表達一點:

Kotlin 協(xié)程并沒有脫離 Kotlin 或者 JVM 創(chuàng)造新的東西,它只是將多線程的開發(fā)變得更簡單了,可以說是因為 Kotlin 的誕生而順其自然出現(xiàn)的東西,從語法上看它很神奇,但從原理上講,它并不是魔術。

最后

轉自:到底什么是「非阻塞式」掛起?協(xié)程真的更輕量級嗎?

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容