fix: 增加描述

This commit is contained in:
xiaoyan 2023-03-02 18:08:00 +08:00
parent 0ede383062
commit c160611e89

View File

@ -37,14 +37,74 @@
如上面代码所示Kotlin中创建启动协程主要有3种方式
1. runBlocking - 启动一个阻塞式协程协程体代码块内代码会阻塞所在线程返回值为泛型T就是在协程体内最后一行返回的数据类型
2. launch - 启动一个非阻塞式协程必须在协程作用域CoroutineScope内启动但不会阻塞所在线程返回值为Job
3. async - 启动一个非阻塞式协程必须在协程作用域CoroutineScope内启动但不会阻塞所在线程返回值为一个Deferred<T>T泛型为协程体内最后一行返回的数据类型
3. async - 启动一个非阻塞式协程必须在协程作用域CoroutineScope内启动但不会阻塞所在线程返回值为一个Deferred<T>T泛型为协程体内最后一行返回的数据类型
- 协程的返回类型
1. runBlocking的泛型返回值T
runBlocking在默认情况下类似于一个封装好的方法当然可以通过指定该方法运行的线程让这个方法不阻塞主线程这样就类似于我们在Java中的Thread并且将run方法执行的结果最终返回回来这里不做过多讨论。
2. launch的返回类型Job
3. async的返回类型Deferred<T>
2. launch的返回类型Job
Job我们可以认为他就是一个协程作业是通过CoroutineScope.launch生成的同时它运行一个指定的代码块并在该代码块完成时完成。我们可以通过isActive、isCompleted、isCancelled来获取到Job的当前状态
我们可以通过Job获取当前协程执行的状态如下表所示协程也存在对应的生命周期。
| State | [isActive] | [isCompleted] | [isCancelled] |
| ----- | :--------: | :-----------: | :----------: |
| New (optional initial state) | false | false | false |
| Active (default initial state)| true | false | false |
| Completing (transient state) | true | false | false |
| Cancelling (transient state) | false| false | true |
| Cancelled (final state) | false | true | true |
| Completed (final state) | false |true| false |
3. async的返回类型Deferred<T>
Deferred是继承自Job的我们可以通过Deferred.await()方法获取协程的泛型T返回值。
## 0x12 详解协程参数
上面的三种创建启动协程的方法,其构造方法内的参数都很类似。
```Kotlin
public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
):
```
可以看到runBlocking相比其他两个方法缺少了协程启动模式CoroutineStart类型的参数三个方法参数都有协程下上文CoroutineContext和协程执行体CoroutineScope.()。接下来我们就主要了解这三个参数类型。
- 协程上下文CoroutineContext
它是一个包含了用户定义的一些各种不同元素的Element对象集合。其中主要元素是Job、协程调度器CoroutineDispatcher、还有包含协程异常CoroutineExceptionHandler、拦截器ContinuationInterceptor、协程名CoroutineName等。这些数据都是和协程密切相关的每一个Element都一个唯一key。
通过协程上下文,我们可以定义协程调度器、协程名称、协程的异常处理方式等等,而这些都可以通过协程上下文中的重载关键字来实现。
- 协程调度器CoroutineDispatcher
如上文所述,协程调度器也实现了协程上下文的接口,协程调度器可以指定当前协程所在的线程。
Kotlin默认提供了4中类型的协程调度线程
- Default默认调度器CPU密集型任务调度器适合处理后台计算。通常处理一些单纯的计算任务或者执行时间较短任务。比如Json的解析数据计算等。
- IOIO调度器IO密集型任务调度器适合执行IO相关操作。比如网络处理数据库操作文件操作等。
- MainUI调度器 即在主线程上执行通常用于UI交互刷新等。
- Unconfined非受限调度器又或者称为“无所谓”调度器不要求协程执行在特定线程上。
不指定调度器时协程运行在Default默认调度器下需要注意的是Default调度器对应的线程并非为主线程。
- 协程启动模式
CoroutineStart协程启动模式是启动协程时需要传入的第二个参数。协程启动有4种
- DEFAULT 默认启动模式,我们可以称之为饿汉启动模式,因为协程创建后立即开始调度,虽然是立即调度,单不是立即执行,有可能在执行前被取消。
- LAZY 懒汉启动模式启动后并不会有任何调度行为直到我们需要它执行的时候才会产生调度。也就是说只有我们主动的调用Job的start、join或者await等函数时才会开始调度。
- ATOMIC 一样也是在协程创建后立即开始调度但是它和DEFAULT模式有一点不一样通过ATOMIC模式启动的协程执行到第一个挂起点之前是不响应cancel 取消操作的ATOMIC一定要涉及到协程挂起后cancel 取消操作的时候才有意义。
- UNDISPATCHED 协程在这种模式下会直接开始在当前线程下执行,直到运行到第一个挂起点。这听起来有点像 ATOMIC不同之处在于UNDISPATCHED是不经过任何调度器就开始执行的。当然遇到挂起点之后的执行将取决于挂起点本身的逻辑和协程上下文中的调度器。
这里需要特别注意的是UNDISPATCHED非调度启动模式在这个模式下协程会在父协程所在线程直接执行直到挂起函数出现如果指定了对应的调度器则会切换到对应的线程执行。
-