协程 kotlincn.net
启动一个协程
GlobalScope.launch {
}
runBlocking {
launch {
}
}
结构化的并发
fun main() = runBlocking {
}
即使用同一个协程。我们可以在这个作用域中启动协程而无需显式 join 之,
因为外部协程直到在其作用域中启动的所有协程都执行完毕后才会结束
作用域构建器
除了由不同的构建器提供协程作用域之外,还可以使用 coroutineScope 构建器声明自己的作用域。
它会创建一个协程作用域并且在所有已启动子协程执行完毕之前不会结束
runBlocking {
coroutineScope { // 创建一个协程作用域
}
}
提取函数重构
挂起函数。加suspend
suspend fun doWorld() {
}
协程很轻量
fun main() = runBlocking {
repeat(100_000) { // 启动大量的协程
launch {
delay(5000L)
print(".")
}
}
}
它启动了 10 万个协程,并且在 5 秒钟后,每个协程都输出一个点。
全局协程像守护线程
fun main() = runBlocking {
GlobalScope.launch {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L) // 在延迟后退出
}
在 GlobalScope 中启动的活动协程并不会使进程保活。它们就像守护线程。
同步异步
withContext
val result = withContext(coroutineContext) {
"这个值会返回给 result"
}
runBlocking
runBlocking {}
join
// Job.join方法可以同步等待协程的完成,就像thread的join一样
val job = launch {} // launch 非阻塞
job.join() // join 阻塞
相当于 sleep
Thread.sleep() // 等待 占用资源
launch
launch {}
协程的 delay
delay() // 等待 但释放资源
协程的 async
// async 异步执行
val async = async {
delay(1000)
"这个值会返回给 result" // 返回值
}
// await 同步等待
val result = async.await() // 挂起等待,直到 async 计算完成,result 接收返回值
协程上下文与调度器
newSingleThreadContext("CtxA").use { ctxA ->
newSingleThreadContext("CtxB").use { ctxB ->
runBlocking(ctxA) {
log("Started in ctxA")
withContext(ctxB) {
log("Working in ctxB")
}
log("Back to ctxA")
}
}
}
Job 协程的 Job 是上下文的一部分
然而,当使用 GlobalScope 来启动一个协程时,则新协程的作业没有父作业。 因此它与这个启动的作用域无关且独立运作。