标签:协程体 suspend 协程 coroutine facilities 夯实 思考 println
协程的基础设施层工具
- 包都是kotlin.coroutine
- 只有suspend、CoroutineContext、Continuation等概念
import kotlin.coroutines.*
fun main() {
coroutine_basic_facilities()
coroutine_basic_facilities_2()
}
/**
* 使用kotlin.coroutine包下的基础设施工具执行协程
* createCoroutine
*/
fun coroutine_basic_facilities() {
println("******begin basic facilities coroutine createCoroutine********")
//挂起函数可以创建协程体createCoroutine,还可以创建并执行startCoroutine
val continuation : Continuation<Unit> = suspend {
//协程体要执行的内容就是挂起函数的内容
Thread.sleep(1000)
println("suspend function execute at ${Thread.currentThread().name}")
5
}.createCoroutine(object : Continuation<Int> {
//协程体存储协程上下文实际上就是通过coroutineContext保存的
override val context: CoroutineContext = EmptyCoroutineContext
//协程体执行完恢复的回调
override fun resumeWith(result: Result<Int>) {
println("resumeWith after suspend function finish with $result at ${Thread.currentThread().name}")
}
})
//如果调用createCoroutine则需要手动触发协程体的恢复
continuation.resume(Unit)
//由于协程并不会阻塞挂起函数以外的代码执行,而只是在调用协程的线程记录协程执行,并最终在协程体执行完成后,在该线程恢复。
// 如果不让外部线程等待,则主线程推出了,协程恢复的时候协程结果都没法输出
Thread.sleep(2000)
println("******finish basic facilities coroutine********")
}
/**
* 使用kotlin.coroutine包下的基础设施工具执行协程
* startCoroutine
*/
fun coroutine_basic_facilities_2() {
println("******begin basic facilities coroutine startCoroutine********")
//挂起函数可以创建协程体createCoroutine,还可以创建并执行startCoroutine
val continuation = suspend {
//协程体要执行的内容就是挂起函数的内容
Thread.sleep(1000)
println("suspend function execute at ${Thread.currentThread().name}")
5
}.startCoroutine(object : Continuation<Int> {
//协程体存储协程上下文实际上就是通过coroutineContext保存的
override val context: CoroutineContext = EmptyCoroutineContext
//协程体执行完恢复的回调
override fun resumeWith(result: Result<Int>) {
println("resumeWith after suspend function finish with $result at ${Thread.currentThread().name}")
}
})
//由于协程并不会阻塞挂起函数以外的代码执行,而只是在调用协程的线程记录协程执行,并最终在协程体执行完成后,在该线程恢复。
// 如果不让外部线程等待,则主线程推出了,协程恢复的时候协程结果都没法输出
Thread.sleep(2000)
println("******finish basic facilities coroutine********")
}
协程的框架业务层工具
- 包都是kotlinx.coroutine
- 有CoroutineScope、Job已经各种诸如delay的函数
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.system.measureTimeMillis
suspend fun main() {
println("******begin framework facilities coroutine********")
var cost : Long
val firstJob = GlobalScope.launch {
cost = measureTimeMillis {
suspendOne("firstJob")
suspendTwo(6, "firstJob")
}
println("first coroutine cost $cost")
}
val secondJob = GlobalScope.launch {
//注意,这里两个协程不阻塞,很快执行完了,但是协程体会在执行完后又在该上下文中恢复
cost = measureTimeMillis {
GlobalScope.launch {
suspendOne("secondJob")
}
GlobalScope.launch {
suspendTwo(4, "secondJob")
}
}
println("second coroutine cost $cost")
}
println("******sleep framework facilities coroutine********")
firstJob.join()
secondJob.join()
println("******finish framework facilities coroutine ********")
}
suspend fun suspendOne(callName : String) {
delay(1000)
println("$callName suspendOne return 23")
23
}
suspend fun suspendTwo(origin : Int, callName: String) {
delay(2000)
println("$callName suspendOne return ${origin * 2}")
origin * 2
}
协程体
Cotinuation就是协程体,是suspend挂起函数的Receiver。
这也是挂起函数可以调用普通函数,但是普通函数无法直接调用挂起函数的原因。
协程体中的CoroutineContext是保存协程上下文现场的关键,协程恢复现场就是使用了这里的数据。
挂起函数并没有挂起,而是协程体挂起了。
而协程体会在协程调度器中运行,即使是在主线程上运行也如此,如Dispatchers.Main、Dispatchers.IO、Dispatchers.Default
协程挂起点在协程调度器执行完协程后会恢复,然后将协程体挂起点后面的部分(恢复上下文)执行完
挂起函数
挂起函数并不是真的挂起,而是告诉编译器这个函数可能会耗时,而协程体才是挂起函数的Receiver,协程体才会挂起和恢复。注意两个概念:
- 协程体相对于当前线程会挂起和恢复
- 协程体在协程调度器中按照顺序执行,并在执行完后回到挂起点进行恢复
标签:协程体,suspend,协程,coroutine,facilities,夯实,思考,println 来源: https://blog.csdn.net/jinc928/article/details/122162530
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。