Kotlin協程入門
- 2021 年 9 月 24 日
- 筆記
開發環境
- IntelliJ IDEA 2021.2.2 (Community Edition)
- Kotlin: 212-1.5.10-release-IJ5284.40
介紹Kotlin中的協程。用一個例子來展示協程的基本用法。
第一個例子
新建工程
我們使用的是社區版IntelliJ IDEA 2021.2.2。新建一個Kotlin工程用來測試。
引入協程
項目用gradle進行管理,我們在Github上找到協程的依賴。
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
}
修改項目的gradle配置。把依賴添加進去。
代碼示例
創建一個類然後在main
方法中寫協程的相關代碼。
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
fun main() {
GlobalScope.launch { // 在後台啟動一個新的協程並繼續
delay(300) // 等待300毫秒
"rustfisher.com".forEach {
print(it)
delay(200) // 每次打印都等待一下
}
}
println("RustFisher")
Thread.sleep(3000) // 阻塞主線程防止過快退出
}
代碼運行結果
本質上,協程是輕量級的線程。
我們用GlobalScope啟動了一個新的協程,這意味着新協程的生命周期只受整個應用程序的生命周期限制。
可以將 GlobalScope.launch { …… }
替換為 thread { …… }
,並將 delay(……)
替換為 Thread.sleep(……)
達到同樣目的。注意導入包kotlin.concurrent.thread
協程換成線程
import java.lang.Thread.sleep
import kotlin.concurrent.thread
fun main() {
thread {
sleep(300)
"rustfisher.com".forEach {
print(it)
sleep(200)
}
}
println("RustFisher")
sleep(3000) // 阻塞主線程防止過快退出
}
如果thread{}
中含有delay
,編譯器會報錯
Suspend function ‘delay’ should be called only from a coroutine or another suspend function
因為delay
是一個特殊的掛起函數,它不會造成線程阻塞,但是會掛起協程,並且只能在協程中使用。
至此,小結一下第一個協程示例
- gradle引入協程
kotlinx-coroutines-core
GlobalScope.launch
啟動協程- 協程中的掛起函數
delay(long)
可以達到延時的效果,並且它只能在協程中使用
協程所在線程
本質上協程是輕量級的線程。我們觀察一下協程所處的線程信息。
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.lang.Thread.sleep
fun main() {
println("main線程信息 ${Thread.currentThread().id}")
for (i in 1..3) { // 多啟動幾次協程
GlobalScope.launch {
println("協程啟動#$i 所在線程id: ${Thread.currentThread().id}")
}
}
sleep(2000) // 阻塞主線程防止過快退出
println("RustFisher 示例結束")
}
運行log如下
main線程信息 1
協程啟動#1 所在線程id: 11
協程啟動#3 所在線程id: 14
協程啟動#2 所在線程id: 13
RustFisher 示例結束
可以看到多次啟動協程,這些協程它們不一定在同一個線程中。也就是說有在同一個線程的可能性。
於是試試瘋狂地啟動協程,把循環次數加大for (i in 1..3000)
。觀察log可以看出,有重複的線程id。