什么是協(xié)程颤专?
來源于維基百科:協(xié)程(英語:coroutine)是計算機程序的一類組件纽哥,推廣了協(xié)作式多任務的子程序,允許執(zhí)行被掛起與被恢復栖秕。相對子例程而言春塌,協(xié)程更為一般和靈活,但在實踐中使用沒有子例程那樣廣泛。協(xié)程更適合于用來實現彼此熟悉的程序組件只壳,如協(xié)作式多任務俏拱、異常處理、事件循環(huán)吼句、迭代器锅必、無限列表和管道。
-
協(xié)程的概念沒有統(tǒng)一的定義惕艳,kotlin的協(xié)程就是kotlin官方提供的一套API搞隐,就是一套線程框架,好在哪里:方便远搪,最方便的地方在同一個代碼塊內進行多次線程的切換
image.png
總結一下劣纲,不要想的那么難,就是:
- 協(xié)程就是一個線程框架
- 協(xié)程掛起的本質就是線程切出去再切回來
為什么需要協(xié)程谁鳍?非阻塞式掛起
方便癞季,借助了kotlin的語言優(yōu)勢,其實最有用的是:用同步的方式寫出異步代碼倘潜,就是說:非阻塞式掛起绷柒。
-
其實這一點我個人感覺好像和es7 差不多呀,前段時間自己寫了一個小程序涮因,看下里面的代碼辉巡,就是好多語言都在使用這個特性
image.png
image.png
- 線程阻塞很好理解,現實中的例子就是交通堵塞蕊退,它的核心有 3 點:
1郊楣、前面有障礙物,你過不去(線程卡了)
2瓤荔、需要等障礙物清除后才能過去(耗時任務結束)
3净蚤、除非你繞道而行(切到別的線程) - 非阻塞式掛起:因為掛起,肯定不在一個線程了输硝,就涉及到多線程了今瀑,線程阻塞其實是對單線程來說的,一旦切了線程点把,那肯定是非阻塞的橘荠,跑到別的線程了,之前的線程就自由了
一句話:非阻塞式掛起就是講協(xié)程在掛起的同時切線程這件事情
阻塞的本質
首先郎逃,所有的代碼本質上都是阻塞式的哥童,而只有比較耗時的代碼才會導致人類可感知的等待,比如在主線程上做一個耗時 50 ms 的操作會導致界面卡掉幾幀褒翰,這種是我們人眼能觀察出來的贮懈,而這就是我們通常意義所說的「阻塞」匀泊。
舉個例子,當你開發(fā)的 app 在性能好的手機上很流暢朵你,在性能差的老手機上會卡頓各聘,就是在說同一行代碼執(zhí)行的時間不一樣。
網絡 IO 的例子抡医,IO 阻塞更多是反映在「等」這件事情上躲因,它的性能瓶頸是和網絡的數據交換,你切多少個線程都沒用忌傻,該花的時間一點都少不了毛仪。
而這跟協(xié)程半毛錢關系沒有,切線程解決不了的事情芯勘,協(xié)程也解決不了箱靴。
協(xié)程與線程
協(xié)程就是基于線程來實現的一種更上層的工具 API,類似于 Java 自帶的 Executor 系列 API 或者 Android 的 Handler 系列 API荷愕。
只不過呢衡怀,協(xié)程它不僅提供了方便的 API,在設計思想上是一個基于線程的上層框架安疗,你可以理解為新造了一些概念用來幫助你更好地使用這些 API抛杨,僅此而已。
Kotlin 協(xié)程的三大疑問:協(xié)程是什么荐类、掛起是什么怖现、掛起的非阻塞式?
1.協(xié)程就是切線程
2.掛起就是可以自動切回來的切線程
3.掛起的非阻塞式指的是它能用看起來阻塞的代碼寫出非阻塞的操作
- Kotlin 協(xié)程并沒有脫離 Kotlin 或者 JVM 創(chuàng)造新的東西,它只是將多線程的開發(fā)變得更簡單了玉罐,可以說是因為 Kotlin 的誕生而順其自然出現的東西屈嗤,從語法上看它很神奇
@Deprecated
-
suspend 函數,掛起函數吊输,是個關鍵字饶号,不會柱塞線程
image.png
suspend 關鍵字作用:提醒作用,提醒我是一個耗時函數季蚂,你需要在協(xié)程里面調用茫船,提醒能讓我們主線程不卡,并沒有實際上去掛起
到底什么是「非阻塞式」掛起扭屁?協(xié)程真的比線程更輕量級嗎算谈?
「非阻塞式」掛起
不卡線程=非阻塞式料滥。java Thread 也是「非阻塞式」協(xié)程就是切線程幔欧,掛起就是可以自動切回來的切線程礁蔗,非阻塞是指的是協(xié)程可以用開起來阻塞的代碼協(xié)程非阻塞的操作
-
kotlin官方文檔的錯誤:同時執(zhí)行10萬個延時任務晒骇,用協(xié)程沒有問題洪囤,用線程多半要內存溢出
image.png
image.png
- tks
- 碼上開學