@@ -10,6 +10,7 @@ Kotlin Coroutine
10
10
2 . Channel
11
11
2 . select
12
12
2 . 协程中的并发同步
13
+ 2 . 协程中的异常
13
14
2 .
14
15
15
16
#### 启动协程
@@ -74,4 +75,28 @@ Kotlin 协程解决并发的两大思路,分别是 Java 思路、协程思路
74
75
3 . 第三种手段,Kotlin 官方提供的 Actor,这是一种普遍存在的并发模型。在目前的版本当中,Kotlin 的 Actor 只是 Channel 的简单封装,它的 API 会在未来的版本发生改变。
75
76
4 . 第四种手段,借助函数式思维。我们之所以需要处理多线程同步问题,主要还是因为存在共享的可变状态。其实,共享可变状态,既不符合无副作用的特性,也不符合不变性的特性。当我们借助函数式编程思维,实现无副作用和不变性以后,并发代码也会随之变得安全。
76
77
78
+ #### 异常
79
+
80
+ 在 Kotlin 协程当中,异常主要分为两大类,一类是协程取消异常(CancellationException),另一类是其他异常。为了处理这两大类问题,有 6 大准则需要知道。
81
+
82
+ 1 . 协程的取消需要内部的配合
83
+
84
+ 2 . 不要轻易打破协程的父子结构
85
+
86
+ 这一点,其实不仅仅只是针对协程的取消异常,而是要贯穿于整个协程的使用过程中。我们知道,协程的优势在于结构化并发,它的很多特性都是建立在这个特性之上的,如果我们无意中打破了它的父子结构,就会导致协程无法按照预期执行。
87
+
88
+ 3 . 捕获了 CancellationException 以后,要考虑是否应该重新抛出来
89
+
90
+ 在协程内部,协程是依赖于 CancellationException 来实现结构化取消的,有的时候我们出于某些目的需要捕获 CancellationException,但捕获完以后,我们还需要思考是否需要将其重新抛出来。
91
+
92
+ 4 . 不要使用 try-catch 直接包裹 launch、async
93
+
94
+ 考虑到协程代码的执行顺序与普通程序不一样,我们直接使用 try-catch 包裹 launch、async 是不会有任何效果的。
95
+
96
+ 5 . 灵活使用 SupervisorJob,控制异常传播的范围
97
+
98
+ SupervisorJob 是一种特殊的 Job,它可以控制异常的传播范围。普通的 Job,它会因为子协程当中的异常而取消自身,而 SupervisorJob 则不会受到子协程异常的影响。在很多业务场景下,我们都不希望子协程影响父协程,所以 SupervisorJob 的应用范围也非常广。比如说 Android 当中的 viewModelScope,它就使用了 SupervisorJob,这样一来,我们的 App 就不会因为某个子协程的异常导致整个应用的功能出现紊乱。
99
+
100
+ 6 . 使用 CoroutineExceptionHandler 处理复杂结构的协程异常,它仅在顶层协程中起作用。传统的 try-catch 在协程当中并不能解决所有问题,尤其是在协程嵌套层级较深的情况下。Kotlin 官方为我们提供了 CoroutineExceptionHandler 作为补充,有了它,我们可以轻松捕获整个作用域内的所有异常。
101
+
77
102
####
0 commit comments