Kotlin?協(xié)程思維模型的引入使用建立
1.協(xié)程
協(xié)程不是進(jìn)程或線程,它的執(zhí)行過程更類似于子例程或者說不帶返回值的函數(shù)調(diào)用。
一個(gè)程序可以包含多個(gè)協(xié)程,類似于一個(gè)進(jìn)程包含多個(gè)線程。線程有自己的上下文多個(gè)線程存在時(shí)它們相對獨(dú)立,切換受系統(tǒng)控制,而協(xié)程也相對獨(dú)立,也有自己的上下文,但是切換是由自己控制的,當(dāng)需要切換到其他協(xié)程時(shí)是由當(dāng)前協(xié)程控制的。
| 線程 | 協(xié)程 | |
|---|---|---|
| 獨(dú)立性 | 相對獨(dú)立 | 相對獨(dú)立 |
| 上下文 | 有自己的上下文 | 有自己的上下文 |
| 切換 | 系統(tǒng)決定是否切換 | 當(dāng)前協(xié)程決定是否切換 |
2.Kotlin協(xié)程
1.引入Kotlin協(xié)程
Kotlin中如果要使用協(xié)程是需要添加依賴的,它沒有被集成在標(biāo)準(zhǔn)庫中,單獨(dú)拎出來主要是為了減小標(biāo)準(zhǔn)庫的體積
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
那么要如何理解Kotlin協(xié)程?Kotlin協(xié)程可以理解為更輕量級(jí)的線程,協(xié)程的運(yùn)行離不開線程,這有點(diǎn)像線程和進(jìn)程之間的關(guān)系。
2.Kotlin協(xié)程的使用
fun main() = runBlocking {
doWorld()
}
suspend fun doWorld() = coroutineScope {
launch {
delay(1000L)
println("World!")
}
println("Hello")
}
//輸出結(jié)果:
//Hello
//World!
上面的代碼是Kotlin協(xié)程的一個(gè)簡單例子其中runBlocking、coroutineScope、launch是協(xié)程作用域,suspend是掛起,delay(1000L)是一個(gè)延時(shí)函數(shù)。從結(jié)果來看我們的代碼順序和輸出結(jié)果的順序不一樣,這就是Kotlin協(xié)程的魅力,我們看下面的流程圖:

3.Kotlin協(xié)程的輕量(總結(jié)的還不夠清晰)
- 啟動(dòng) 10 億個(gè)線程,這樣的代碼運(yùn)行在大部分的機(jī)器上都是會(huì)因?yàn)閮?nèi)存不足等原因而異常退出的。那么啟動(dòng)10億個(gè)協(xié)程則不會(huì)出現(xiàn)異常因?yàn)閰f(xié)程是非常輕量的;
- 協(xié)程雖然是運(yùn)行在線程上的但是它并不會(huì)與某個(gè)線程綁定,而且還可以在不同線程之間切換。
4.協(xié)程的“非阻塞式”
線程是阻塞的,因?yàn)樗谶\(yùn)行一個(gè)耗時(shí)任務(wù)時(shí)只有這個(gè)任務(wù)完成了才會(huì)執(zhí)行后面的任務(wù),而Kotlin在執(zhí)行一個(gè)耗時(shí)任務(wù)時(shí)會(huì)把這個(gè)任務(wù)放入后臺(tái)執(zhí)行,去執(zhí)行下一個(gè)任務(wù)。
fun main() {
repeat(3) {
Thread.sleep(1000L)
println("Print-1:${Thread.currentThread().name}")
}
repeat(3) {
Thread.sleep(900L)
println("Print-2:${Thread.currentThread().name}")
}
}
/*
輸出結(jié)果:
Print-1:main
Print-1:main
Print-1:main
Print-2:main
Print-2:main
Print-2:main
*/
上面的代碼是阻塞式任務(wù),可以看到兩個(gè)任務(wù)之間的等待時(shí)差是100毫秒,但是第二個(gè)repeat執(zhí)行的前提是第一個(gè)repeat執(zhí)行完畢,那么這個(gè)任務(wù)的最終耗時(shí)就是5700毫秒。
fun main() = runBlocking {
launch {
repeat(3) {
delay(1000L)
println("Print-1:${Thread.currentThread().name}")
}
}
launch {
repeat(3) {
delay(900L)
println("Print-2:${Thread.currentThread().name}")
}
}
delay(3000L)
}
/*
輸出結(jié)果:
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
Print-2:main @coroutine#3
Print-1:main @coroutine#2
*/
上面的代碼是非阻塞式任務(wù),可以看到兩個(gè)任務(wù)之間的等待時(shí)差是100毫秒,第以個(gè)repeat和第二個(gè)repeat是同時(shí)執(zhí)行的,也就是說他們同時(shí)開始執(zhí)行,當(dāng)達(dá)到900毫秒時(shí)第二個(gè)repeat開始執(zhí)行,當(dāng)達(dá)到1000毫秒時(shí)第一個(gè)repeat開始執(zhí)行,那么這個(gè)任務(wù)的最終耗時(shí)就是3000毫秒。
由此可見,Kotlin 協(xié)程的“非阻塞”其實(shí)只是語言層面的,當(dāng)我們調(diào)用 JVM 層面的 Thread.sleep() 的時(shí)候,它仍然會(huì)變成阻塞式的。與此同時(shí),這也意味著我們在協(xié)程當(dāng)中應(yīng)該盡量避免出現(xiàn)阻塞式的行為。盡量使用 delay,而不是 sleep。
到這里其實(shí)就會(huì)產(chǎn)生一個(gè)疑問,delay就能解決阻塞的問題嗎?答案是不是,解決阻塞問題的其實(shí)是Kotlin的掛起和恢復(fù)的能力,這是協(xié)程才擁有的特殊能力。
掛起和恢復(fù)又該怎么理解呢,舉個(gè)例子,現(xiàn)在有兩件事情:①燒一壺水燒開后斷開電源;②做飯;第一件事是一個(gè)耗時(shí)任務(wù),開始燒水后我去做第二件事這就是掛起,當(dāng)水燒開以后要去斷開電源這就是恢復(fù)。
5.建立思維模型
Kotlin的協(xié)程要比Java線程更抽象,因?yàn)镴ava的線程可以找到Thread的源碼,同時(shí)線程也是操作系統(tǒng)中的一個(gè)概念,所以理解起來較為簡單。而Kotlin的協(xié)程沒有類似的知識(shí)點(diǎn)可以建立關(guān)聯(lián),所以在學(xué)習(xí)Kotlin協(xié)程的時(shí)候就需要簡歷協(xié)程的思維模型, 沒有這個(gè)思維理解Kotlin協(xié)程就比較難。
如何建立Kotlin的思維模型?可以將Kotlin協(xié)程想象成一個(gè)“更加輕量級(jí)的線程”。

從包含關(guān)系上看,協(xié)程跟線程的關(guān)系,有點(diǎn)像線程與進(jìn)程的關(guān)系,畢竟協(xié)程不可能脫離線程運(yùn)行。所以,協(xié)程可以理解為運(yùn)行在線程當(dāng)中的、更加輕量的 Task。

以上就是Kotlin 協(xié)程思維模型的引入使用建立的詳細(xì)內(nèi)容,更多關(guān)于Kotlin 協(xié)程思維模型的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決Android Studio突然不顯示logcat日志的問題
這篇文章主要介紹了解決Android Studio突然不顯示logcat日志的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Android自定義View實(shí)現(xiàn)打字機(jī)效果
最近在做Android開發(fā)的時(shí)候,需要做類似于打字機(jī)打字的效果,字一個(gè)一個(gè)地蹦出來,顯示每一個(gè)字都帶有打字的聲音?,F(xiàn)在分享給大家,有需要的可以參考借鑒。2016-08-08
Android RecyclerView自由拖動(dòng)item的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android RecyclerView自由拖動(dòng)item的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Flutter實(shí)現(xiàn)文本滾動(dòng)高亮效果的示例講解
這篇文章主要介紹了如何利用Flutter時(shí)時(shí)渲染頁面從而達(dá)到文本滾動(dòng)高亮的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-03-03
Android?RecyclerBarChart繪制使用教程
這篇文章主要為大家介紹了Android?RecyclerBarChart繪制使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Android Back鍵點(diǎn)擊兩次退出應(yīng)用詳解及實(shí)現(xiàn)方法總結(jié)
這篇文章主要介紹了Android Back鍵點(diǎn)擊兩次退出應(yīng)用詳解及實(shí)現(xiàn)方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2016-10-10
Android監(jiān)聽滑動(dòng)控件實(shí)現(xiàn)狀態(tài)欄顏色切換
這篇文章給大家分享一個(gè)平時(shí)在滑動(dòng)頁面經(jīng)常遇到的效果:滑動(dòng)過程動(dòng)態(tài)修改狀態(tài)欄顏色,文中有詳細(xì)的示例代碼,對我們的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴自己動(dòng)手試試吧2023-08-08
ijkPlayer播放器的全自動(dòng)編譯腳本及最終編譯包
這篇文章主要介紹了ijkPlayer播放器的全自動(dòng)編譯腳本及最終編譯包,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

