coroutie-start2

runblocking会等待子协程执行完成.

https://www.bilibili.com/video/BV1uo4y1y7ZF?p=24&spm_id_from=pageDriver

P20 launch async

Laugh 返回一个Job

Async , 返回Deffrred.

2021-12-13_1.04.30

Async 返回执行结果

1
2
3
4
5
Job1 finished.

Job2 finished

Job2 finished
P21 join与await等待协程的作业
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Test
fun `test coroutine join`() = runBlocking {
val job1 = launch() {
delay(200)
println("One")
}
job1.join() // job1执行完,再执行job2 job3
val job2 = launch() {
delay(200)
println("Two")
}
val job3 = launch() {
delay(200)
println("Three")
}
}

@Test
fun `test coroutine await`() = runBlocking {
// 刷新界面,拿到执行结果后,再执行其他的。
val job1 = async() {
delay(200)
println("One")
}
job1.await() // job1执行完,再执行job2 job3
val job2 = async() {
delay(200)
println("Two")
}
val job3 = async() {
delay(200)
println("Three")
}
}

区别是await可以拿到执行结果,

接口1请求成功,拿到接口,再请求其他接口。

launch启动用 join()

async启动用 await()

P22 async组合并发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Test
fun `test sync`() = runBlocking {
val time = measureTimeMillis {
val one = doOne() // 同步,串行任务
val two = doTwo()
println("The result : ${one + two}")
}
println("completed in $time ms")
}

@Test
fun `test combine async`() = runBlocking {
val time = measureTimeMillis {
val one = async{doOne()} // 并发的两个异步任务
val two = async{doTwo()}
println("The result : ${one.await() + two.await()}")
}
println("completed in $time ms")
}

private suspend fun doOne(): Int {
delay(1000)
return 14
}

private suspend fun doTwo(): Int {
delay(1000)
return 25
}

执行的结果相加

协程的启动模式

coroutie-start2

CoroutineStart.DEFAULT

p24 协程的作用域构建器

runBlocking阻塞当前线程等待

coroutie-start2

1
2
3
4
5
6
7
8
9
10
coroutineScope {
val job1 = launch {
delay(1000)
println("Job1 finished.")
}
val job2 = async {
delay(1000)
println("Job2 finished.")
}
}

coroutineScope 也需要等待子协程执行结束,和 runBlocking很像.

区别coroutineScope是挂起函数.

coroutineScope与supervisorScope

还有SupervisorJob

coroutie-start2

1
2
3
4
5
6
7
8
9
10
11
coroutineScope {
val job1 = launch {
delay(400)
println("Job1 finished.")
}
val job2 = async {
delay(200)
println("Job2 finished.")
"job2 result"
}
}

Job2 finished.
Job1 finished.

job2中断 job1也中断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
fun `test coroutineScope scope builder`() = runBlocking {
coroutineScope {
val job1 = launch {
delay(400)
println("job1 finished.")
}
val job2 = launch {
delay(200)
println("job2 finished.")
"job2 result"
throw IllegalArgumentException()
}
}
}

job2 finished.

java.lang.IllegalArgumentException

两个协程都退出

job2中断 job1继续

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
fun `test supervisorScope scope builder`() = runBlocking {
supervisorScope {
val job1 = launch {
delay(400)
println("job1 finished.")
}
val job2 = launch {
delay(200)
println("job2 finished.")
"job2 result"
throw IllegalArgumentException()
}
}
}

job2 finished.
Exception in thread “Test worker @coroutine#3”

Job1 finished.

25 Job的生命周期
2022-03-20_10.46.51 2022-03-20_10.47.57

协程的取消

2022-03-20_10.58.25
26-取消作用域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Test
fun `test scope cancel`() = runBlocking<Unit> {
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
delay(1000)
println("Job 1.")
}

scope.launch {
delay(1000)
println("Job 2.")
}
// delay(2000) //需要加这个才能看到 打印,CoroutineScope没有继承runBlocking的上下文
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
fun `test scope cancel`() = runBlocking<Unit> {
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
delay(1000)
println("Job 1.")
}

scope.launch {
delay(1000)
println("Job 2.")
}
delay(100) //需要加这个才能看到 打印
scope.cancel()
delay(2000)
}

CorountineScope和corountineScope的区别(大小写的区别,大写的可以取消)

2022-03-20_11.14.10
P27-取消兄弟协程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
fun `test scope cancel`() = runBlocking<Unit> {
val scope = CoroutineScope(Dispatchers.Default)
val job1 = scope.launch {
delay(1000)
println("Job 1.")
}

val job2=scope.launch {
delay(1000)
println("Job 2.")
}
delay(100) //需要加这个才能看到 打印
job1.cancel()
delay(2000)
}

被取消的协程,不会影响其余的兄弟协程

1
Job 2.
28-协程取消的异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
fun `test CancellationException `() = runBlocking<Unit> {
val job1 = GlobalScope.launch {
try {
delay(1000)
println("Job 1.")
}catch (e:Exception){
e.printStackTrace()
}
}
delay(100)
job1.cancel(CancellationException("取消"))
job1.join() // 否则不会打印GlobalScope不在runBlocking上下文
}

java.util.concurrent.CancellationException: 取消

cpu密集型任务取消

29cpu密集型任务取消 isActive
2022-03-20_11.31.18

isActive判断取消,否则还是计算5次,这个和线程while操作很像

p30- cpu密集型任务取消 - ensureActive

退出循环

2022-03-20_12.17.26

p31-yiled取消
2022-03-20_12.18.27 2022-03-20_12.19.29
p32-coroutine取消副作用
2022-03-20_12.26.32 2022-03-20_12.27.16
p33 标准函数use

自动关闭文件对象

2022-03-20_12.29.38

2022-03-20_12.30.36

34不能取消的任务

NonCancellable

2022-03-20_12.32.18

2022-03-20_12.34.23

35超时任务

网络请求超时

2022-03-20_12.38.56

超时1300后的处理

图片


coroutie-start2
https://noteforme.github.io/2021/12/14/coroutie-start2/
Author
Jon
Posted on
December 14, 2021
Licensed under