本期做者:git
視頻:扔物線(朱凱)github
文章:Lewis(姚文欽)編程
你們好,我是扔物線朱凱。今天又是協程,不過今天有一些不同:api
這期主要是解釋一下掛起的「非阻塞式」是怎麼回事,以及對一些最多見的誤導性言論進行一下平常打臉——固然了目的固然不是打誰的臉,我沒那閒工夫,主要是給你們開個霧。網絡
更多的話就不說了,來看視頻吧:多線程
如下內容來自文章做者 Lewis。app
你們好,協程的素質三連最後一連終於來了,挖坑容易填坑難。框架
這段時間真的太忙了,不過咱們即刻 Android 團隊也對作好「碼上開學」的意義又有了新的認識。編程語言
接觸過大公司的朋友都知道,不少公司會把一些技術的分享列爲公司機密,僅限內部分享,你只有加入了公司以後才能看,而且還不能傳播出來,而這些被列爲機密的東西一般有如下特色:
但願上面說的沒有戳中你所在的公司,這裏沒有任何 diss 的意思,因此咱們要作好「碼上開學」,也但願更多有相同志向的業內同行一塊兒參與進來,經過碼上開學,咱們想表達這樣的技術理念:
在協程系列的前兩篇文章中,咱們介紹了:
由於時間比較久遠了,忘了也很正常,不過今天咱們要說的這個「非阻塞式」的概念,即便你沒有協程的基礎,也能夠看懂。
非阻塞式是相對阻塞式而言的。
編程語言中的不少概念其實都來源於生活,就像脫口秀的段子同樣。
線程阻塞很好理解,現實中的例子就是交通堵塞,它的核心有 3 點:
從語義上理解「非阻塞式掛起」,講的是「非阻塞式」這個是掛起的一個特色,也就是說,協程的掛起,就是非阻塞式的,協程是不講「阻塞式的掛起」的概念的。
咱們講「非阻塞式掛起」,其實它有幾個前提:並無限定在一個線程裏說這件事,由於掛起這件事,原本就是涉及到多線程。
就像視頻裏講的,阻塞不阻塞,都是針對單線程講的,一旦切了線程,確定是非阻塞的,你都跑到別的線程了,以前的線程就自由了,能夠繼續作別的事情了。
因此「非阻塞式掛起」,其實就是在講協程在掛起的同時切線程這件事情。
既然第三篇說的「非阻塞式掛起」和第二篇的「掛起要切線程」是同一件事情,那還有講的必要嗎?
是有的。由於它在寫法上和單線程的阻塞式是同樣的。
協程只是在寫法上「看起來阻塞」,實際上是「非阻塞」的,由於在協程裏面它作了不少工做,其中有一個就是幫咱們切線程。
第二篇講掛起,重點是說切線程先切過去,而後再切回來。
第三篇講非阻塞式,重點是說線程雖然會切,但寫法上和普通的單線程差很少。
讓咱們來看看下面的例子:
🏝️
main {
GlobalScope.launch(Dispatchers.Main) {
// 👇 耗時操做
val user = suspendingRequestUser()
updateView(user)
}
private suspend fun suspendingRequestUser() : User = withContext(Dispatchers.IO) {
api.requestUser()
}
}
複製代碼
從上面的例子能夠看到,耗時操做和更新 UI 的邏輯像寫單線程同樣放在了一塊兒,只是在外面包了一層協程。
而正是這個協程解決了原來咱們單線程寫法會卡線程這件事。
首先,全部的代碼本質上都是阻塞式的,而只有比較耗時的代碼纔會致使人類可感知的等待,好比在主線程上作一個耗時 50 ms 的操做會致使界面卡掉幾幀,這種是咱們人眼能觀察出來的,而這就是咱們一般意義所說的「阻塞」。
舉個例子,當你開發的 app 在性能好的手機上很流暢,在性能差的老手機上會卡頓,就是在說同一行代碼執行的時間不同。
視頻中講了一個網絡 IO 的例子,IO 阻塞更可能是反映在「等」這件事情上,它的性能瓶頸是和網絡的數據交換,你切多少個線程都沒用,該花的時間一點都少不了。
而這跟協程半毛錢關係沒有,切線程解決不了的事情,協程也解決不了。
協程咱們講了 3 期,Kotlin 協程和線程是沒法脫離開講的。
別的語言我不說,在 Kotlin 裏,協程就是基於線程來實現的一種更上層的工具 API,相似於 Java 自帶的 Executor 系列 API 或者 Android 的 Handler 系列 API。
只不過呢,協程它不只提供了方便的 API,在設計思想上是一個基於線程的上層框架,你能夠理解爲新造了一些概念用來幫助你更好地使用這些 API,僅此而已。
就像 ReactiveX 同樣,爲了讓你更好地使用各類操做符 API,新造了 Observable 等概念。
說到這裏,Kotlin 協程的三大疑問:協程是什麼、掛起是什麼、掛起的非阻塞式是怎麼回事,就已經所有講完了。很是簡單:
固然了,這幾句是總結,它們背後的原理你是必定要掌握住的。若是忘了,再去把以前的視頻和文章看一遍就好。
視頻中還糾正了官方文檔裏面的一個錯誤,這裏就再也不重複了,最後想表達一點:
Kotlin 協程並無脫離 Kotlin 或者 JVM 創造新的東西,它只是將多線程的開發變得更簡單了,能夠說是由於 Kotlin 的誕生而順其天然出現的東西,從語法上看它很神奇,但從原理上講,它並非魔術。
但願經過協程系列的講解能幫助讀者上手 Kotlin 協程,再也不以爲懼怕不敢上手,歡迎繼續關注「碼上開學」的後續文章,期待和你共同進步。
使用協程實現一個網絡請求:
Lewis(姚文欽),即刻 Android 工程師。2017年加入即刻,參與即刻 4.0 到 6.0 版本的架構設計和與產品迭代。多年 Android 開發經驗,如今負責 Android 端多媒體中臺基礎建設。