深圳培训手机网站建设,wordpress向小程序获取数据,怎样推广网站,网站建设与维护课件协程定义#xff1a;
19年官方是这样说的#xff1a;协程是轻量级的线程#xff0c;协程就是 Kotlin 提供的一套线程封装的 API#xff1b;
现在官方是这样说的#xff1a;协程是一种并发设计模式#xff1b;
协程作用#xff1a;
1.处理耗时任务#xff1b;
2.保…协程定义
19年官方是这样说的协程是轻量级的线程协程就是 Kotlin 提供的一套线程封装的 API
现在官方是这样说的协程是一种并发设计模式
协程作用
1.处理耗时任务
2.保证主线程的安全
3.简化异步执行的代码解决并发问题让「协作式多任务」实现起来更加方便。
使用协程同样可以像 Rx 那样有效地消除回调地狱不过无论是设计理念还是代码风格两者是有很大区别的协程在写法上和普通的顺序代码类似。
协程特点
轻量您可以在单个线程上运行多个协程因为协程支持挂起不会使正在运行协程的线程阻塞。挂起比阻塞节省内存且支持多个并行操作。
内存泄漏更少使用结构化并发机制在一个作用域内执行多项操作。
内置取消支持取消功能会自动通过正在运行的协程层次结构传播。
协程使用
1.lauch
lauch用于在协程作用域中异步启动一个新的协程调用该方法不会阻塞线程。
CoroutineScope(Dispatchers.IO).launch {// 启动一个非阻塞线程的协程
}
2.suspend
suspend是协程的关键字每一个被suspend修饰的方法都必须在另一个suspend函数或者Coroutine协程程序中进行调用。
3.coroutineScope
coroutineScope是一个挂起函数每一个被suspend修饰的方法都必须在另一个suspend函数或者Coroutine协程程序中进行调用。
CoroutineScope(Dispatchers.IO).launch {coroutineScope {// 启动一个非阻塞线程的协程}
}runBlocking {coroutineScope {// 启动一个非阻塞线程的协程}
}
4.runBlocking
runBlocking会阻塞当前线程而coroutineScope不会阻塞所在的线程它会挂起所在的协程直至其内部任务(包括子协程)执行完成。
runBlocking {// 启动一个阻塞线程的协程
}
5.dispatcher
dispatcher 协程调度器可以控制协程代码块在UI线程还是子线程中执行
6.async
1在概念上async 就类似于 launch。它启动了一个单独的协程与其它所有的协程一起并发的工作。不同之处在于 launch 返回一个 Job 并且不附带任何结果值而 async 返回一个 Deferred接口指向的对象使用 Deferred.await()在一个延期的值上得到它的最终结果同时Deferred 也是一个 Job所以如果需要的话可以使用Deferred.cancel()取消它。
CoroutineScope(Dispatchers.IO).launch {val api1Deferred async { api1() }val api2Deferred async { api2() }val api3Deferred async { api3() }println(api*****1)val result1 api1Deferred.await()println(api*****2)
}suspend fun api1(): String {delay(2500) // 模拟耗时操作println(api1)return api1
}suspend fun api2(): String {delay(2000) // 模拟耗时操作println(api2)return api2
}suspend fun api3(): String {delay(1500) // 模拟耗时操作println(api3)return api3
}
输出结果 结论
async启动的所有协程是一起并发工作的async不是挂起函数所以不会挂起launch创建的协程所以先输出api*****1再api3、api2、api1但执行到api1Deferred.await()时会挂起协程等待async { api1() }执行完返回结果后再执行协程后续的函数所以最后输出api*****2因为await()是挂起函数。
public suspend fun await(): T
2案例有4个耗时方法方法名api1api2api3api4要求方法api1先执行返回String api1然后将结果api1作为参数并发执行方法api2和方法api3由于api3 delay(1500)api2 delay(2000)所以api3会先执行完并输出结果然后api2再执行完并输出结果最后将结果api2api3作为参数执行方法api4。
CoroutineScope(Dispatchers.IO).launch {val api1Deferred async { api1() }println(api*****1)val result1 api1Deferred.await()println(api1:$result1) // 等待 api1 方法执行完成并输出结果val api2Deferred async { api2(result1) }val api3Deferred async { api3(result1) }val result2 api2Deferred.await()println(api2:$result2)val result3 api3Deferred.await()println(api3:$result3)println(api4(result2, result3))
}suspend fun api1(): String {delay(3000) // 模拟耗时操作println(api1)return api1
}suspend fun api2(v: String): String {delay(2000) // 模拟耗时操作println(api2)return api2:$v
}suspend fun api3(v: String): String {delay(1500) // 模拟耗时操作println(api3)return api3:$v
}suspend fun api4(v: String, v2: String): String {delay(500) // 模拟耗时操作return api4:$v$v2
}
输出结果 注async是并行的如果使用await()的话await()是挂起函数会挂起协程等待async { api1() }执行完返回结果后再执行协程后续的函数。
7. withContext
withContext 与 async 都可以返回耗时任务的执行结果。多个 withContext 任务是串行顺序执行的 且withContext 可直接返回耗时任务的结果。 而多个 async 任务是并行的。
public suspend fun T withContext()
因为withContext()是挂起函数执行后会挂起协程等待withContext内部函数执行完后再执行withContext函数后面的函数。
CoroutineScope(Dispatchers.IO).launch {val result1 withContext(Dispatchers.IO) {api1()}println(api*****1)println(api1:$result1) // 等待 api1 方法执行完成并输出结果val result2 withContext(Dispatchers.IO) {api2(result1)}println(api2:$result2)val result3 withContext(Dispatchers.IO) {api3(result1)}println(api3:$result3)val result4 withContext(Dispatchers.IO) {api4(result2, result3)}println(result4)
}suspend fun api1(): String {delay(3000) // 模拟耗时操作println(api1)return api1
}suspend fun api2(v: String): String {delay(2000) // 模拟耗时操作println(api2)return api2:$v
}suspend fun api3(v: String): String {delay(1500) // 模拟耗时操作println(api3)return api3:$v
}suspend fun api4(v: String, v2: String): String {delay(500) // 模拟耗时操作return api4:$v$v2
}
输出结果