构建器
runBlocking
顶层函数
非挂起函数
返回T
,Lambda表达值最后一行
阻塞当前线程,会等待所有其中包含的协程执行完毕
fun main() {
println("before runBlocking: ${Thread.currentThread().name}")
val result = runBlocking {
// 线程:与指定的Dispatchers有关,若不指定,则与runBlocking当前线程一致
println("before delay: ${Thread.currentThread().name}")
delay(200)
println("after delay: ${Thread.currentThread().name}")
1
}
println("after runBlocking: ${Thread.currentThread().name}, result is $result")
// before runBlocking: main
// before delay: main
// after delay: main
// after runBlocking: main, result is 1
}
launch
CoroutineScope
上的扩展函数
挂起函数
返回Job
fun main() {
println("before runBlocking: ${Thread.currentThread().name}")
val result = runBlocking(Dispatchers.IO) {
// 线程:与指定的Dispatchers有关,若不指定,则与runBlocking当前线程一致
println("before launch: ${Thread.currentThread().name}")
launch {
// 线程:与指定的Dispatchers有关,若不指定,则与launch当前线程一致
println("before delay: ${Thread.currentThread().name}")
delay(2000)
println("after delay: ${Thread.currentThread().name}")
}
println("after launch: ${Thread.currentThread().name}")
1
}
println("after runBlocking: ${Thread.currentThread().name}, result is $result")
// before runBlocking: main
// before launch: DefaultDispatcher-worker-1
// after launch: DefaultDispatcher-worker-1
// before delay: DefaultDispatcher-worker-3
// after delay: DefaultDispatcher-worker-3
// after runBlocking: main, result is 1
}
async
CoroutineScope
上的扩展函数
挂起函数
返回Deferred<T>
,并使用await()
获取返回值T
suspend fun main() {
println("suspend main ${Thread.currentThread().name}")
coroutineScope {
println("coroutineScope ${Thread.currentThread().name}")
val first = async {
println("first async ${Thread.currentThread().name}")
add(1, 2)
}
val second = async {
println("second async ${Thread.currentThread().name}")
add(3, 4)
}
println("Awaiting concurrent sums...")
val total = first.await() + second.await()
println("total is $total")
}
// suspend main main
// coroutineScope main
// first async DefaultDispatcher-worker-1
// Awaiting concurrent sums...
// second async DefaultDispatcher-worker-2
// total is 10
}
suspend fun add(x: Int, y: Int): Int {
delay(1000)
return x + y
}
coroutineScope
顶层函数
挂起函数
返回T
,Lambda表达值最后一行
不阻塞主线程(与runBlocking
不同),会等待所有包含的协程执行完毕后才退出。
suspend fun main() {
coroutineScope {
repeat(10) {
launch { // 启动10个协程
delay(1000L - it * 10) // 以递减的时间延迟每个协程
print("❤️$it ")
}
}
}
// ❤️9 ❤️8 ❤️7 ❤️6 ❤️5 ❤️4 ❤️3 ❤️2 ❤️1 ❤️0
}
在
coroutineScope
内运行所有协程以确保如果一个失败,所有协程将被取消的惯例称为结构化并发。
withContext
用于简化async
启动协程后,立即使用await
等待获取结果的情况
suspend fun main() {
val a = 1
val b = withContext(Dispatchers.IO) {
delay(2000)
3
}
println("$a")
println("$b")
println("${a + b}")
}
// 1
// 2
// 4
等价于
suspend fun main() {
val c = 1
val d = coroutineScope {
async(Dispatchers.IO) {
delay(2000)
3
}.await()
}
println("$c")
println("$d")
println("${c + d}")
}
// 1
// 2
// 4
调度器Dispatchers
当使用launch
或async
之类的构建器时,可以通过可选的CoroutineContext
参数指定要使用的调度器。
Dispatchers.Default
普通的共享线程池,适合消耗大量计算资源的协程。
默认情况下,最大并行数等于CPU内核数,但至少为2个。
Dispatchers.IO
按需创建的共享线程池,适合运行I/O密集型的阻塞任务,如文件I/O或阻塞式的网络I/O。
任务使用的线程数受系统属性kotlinx.coroutines.io.parallelism([IO_PARALLELISM_PROPERTY_NAME])
的值的限制,它默认为64个线程或内核数(按较大值)的限制。
最大可配置线程数由系统属性kotlinx.coroutines.scheduler.max.pool.size
限制。
Dispatchers.Main
Android上可使用,需添加kotlinx-coroutines-android
依赖,用于主线程。
Dispatchers.Unconfined
不应该在应用代码中使用。
网友评论