「協程」和「Kotlin 協程」

Tips 0:寫徹底文回頭看,我以爲只看總結也夠了。能夠快進。html

前言

最初接觸 Kotlin 的時候,Kotlin 協程還處於實驗階段,我也是第一次據說協程的概念。幾年過去了,隨着 Kotlin 的推廣和 Kotlin 協程的發展,我終於在去年年末正式入坑了。web

大約5個月的時間,從 demo 用到真實項目,我對 Kotlin 協程的見解也一波三折,從不明覺厲到不過如此,又逐漸變成這東西真不錯。編程

關於 Kotlin 協程我有不少想寫的內容,草稿箱和筆記裏都有不一樣的提綱,但第一篇就仍是從困擾了我最久的點開始講起吧,那就是「協程」的概念和 Kotlin 中的協程。markdown

本文中協程和 Kotlin 協程是兩種並列的不一樣的概念,兩者沒有包含關係。併發

從協程的概念開始

Tips 1:對於還未接觸過協程的人來講,我以爲學習 Kotlin 協程徹底不須要去深刻理解協程自己的概念,由於 Kotlin 協程並非真正的協程,早期過分研究概念和對比區別是學習 Kotlin 協程的一條彎路。app

根據維基百科的介紹,協程並非新技術,這個概念正式發佈於1963年,是一種實現多任務併發的技術思路,大概與「線程」位於同一級別,兩者的區別則是線程採起「搶佔式」策略,而協程採起「協做式」策略。框架

單從概念上看,協程可控性比線程高,彷佛是更優解,但協做式的方案不能實現真正的並行,很顯然,線程取得了勝利。異步

「協程」一度沉寂,但隨着軟件開發的複雜度提高,不少語言都從新撿起了協程的概念來處理異步操做,但具體實現上已經與曾經的協程相去甚遠。異步編程

Kotlin 協程的目標

Kotlin 協程是一個 JetBrains 官方出品的庫,但不包含在 Kotlin 語言標準庫中,目標是解決開發者用很差線程的問題(我編的)。函數

根據官方介紹,Kotlin 協程是用來實現異步任務和非阻塞編程的。以 Android 開發爲例,爲了保證良好的用戶體驗,系統規定 UI 線程不可阻塞,以便馬上響應用戶輸入,全部耗時操做都應該在其餘線程實現,再通知 UI 線程更新頁面。不僅是 Android,全部對外提供服務的程序都有這樣的需求,給了 Kotlin 協程更普遍的發揮空間。

Kotlin 協程的功能

Kotlin 的協程使用了協程的概念,經過「掛起」和「恢復」簡化了多任務協做的實現代碼。Kotlin 協程是一種對同步編程和異步編程統一的抽象封裝。

  • 掛起和恢復

掛起和恢復來自協程的基本概念,每一個協程自身決定什麼時候掛起什麼時候繼續,達成多任務之間協做。

image.png

在一次次調用 suspend 函數的過程當中,表面上連續的調用棧實際上已經完成了線程切換。

被掛起和恢復的對象是協程,也就是說在第一次 suspend 以後線程 A 並未被阻塞,還能夠執行其餘發生在線程 A 的代碼。

  • 多任務

任務是一種抽象概念,能夠理解成一段代碼或者一個函數,執行任務須要必定的時間,任務可能正常完成得到須要的結果,也可能遇到異常而失敗。Kotlin 協程的協做是多任務之間的協做,任務一般在不一樣的線程,但也能夠在相同的線程。(一個掛起函數內也能夠調用普通函數)

  • 關於簡化

只看官方對 Kotlin 協程的介紹可能以爲簡化的做用很大,其實那些例子都沒有處理 Exception,實際應用協程的時候並不會那麼簡單。但簡化代碼並非虛假宣傳,實際上簡化的是恢復的過程,協程恢復的過程是將其餘任務的處理結果傳回來的地方,若是使用回調的話,免不了加一層嵌套,任務越多越複雜。Kotlin 協程的簡化是把這些嵌套拉平了。

一段總結

寫完以後我又反覆讀了文章內容,不斷修改,但仍是以爲漏洞百出。講述概念的每一處用詞都通過了反覆推敲,但仍是會發現先後矛盾、內容重複、歧義等問題。有點只可意會不可言傳的意思了。

總結一下觀點吧:

  1. 當對比協程和線程時,一般是指概念上的協程,與 Kotlin 協程不是同一個東西
  2. Kotlin 協程是一個用協程概念在線程框架上封裝的庫
  3. Kotlin 協程能夠解決異步代碼難寫難讀的問題,但並不是不可替代的黑科技

投降了,講概念太可怕了,下一篇寫 Kotlin 協程和 ViewModel、Retrofit、Room 的實踐。


參考資料:

  1. 協程-維基百科
  2. Coroutine|Kotlin
  3. 《深刻理解 Kotlin 協程》

Tips 2: 《深刻理解 Kotlin 協程》這本書經過橫向對比不一樣語言的協程實現,或者不一樣異步任務實現方案闡述了 Kotlin 協程的各方面特色,也有對源碼的一些講解,重理論輕實踐,最好在有必定的實踐經驗以後再看。

相關文章
相關標籤/搜索