调度器有多种,看下面的例子:
输出结果如下:
当 launch 函数调用的时候,它会从 CoroutineScope 中继承 context,在上面的例子中,它继承的是 runBlocking中的 context,所以运行在主线程。
Dispatchers.Default 使用一个后台的线程池来运行。
newSingleThreadContext 每次会创建一个单独的线程来运行,最好是保存起来,复用同一个。
Dispatchers.Unconfined 这个就比较神奇,它会让线程运行在调用者线程,但是只到第一个挂起点。
看一个例子:
输出结果:
发现了一个神奇的事情,第一个协程中,第二条打印语句跑到了子线程中去了,是被 delay 函数影响到了。
那为啥第二个协程不受影响呢?看一下第一个协程与第二个协程 context 的区别:
notion image
notion image
可以看到是因为第一个设置了 Dispatchers.Unconfined 之后覆盖了原本的 BlockingEventLoop 导致的。前面我们说过,delay 函数在 context 有调度器的情况下是不会添加一个 Default 的,这里也验证了。

子协程

当一个协程在另一个协程的 CoroutineScope 中启动时,它将通过 CoroutineScope.coroutineContext 继承其上下文,新协程的job将成为父协程 job 的子 job。当父协程被取消时,它的所有子协程也会被递归取消。
但是这种父子关系是可以被覆盖的,我们主要说一下 job。
request 协程有两个子协程,一个设置了 job,另一个没有。当取消 request 协程的时候,设置了 job 的协程不会取消。
输出如下:

父协程的责任

父协程会等待所有子协程完成,嗯,这个不是字面上的意思,而是说,父协程的逻辑可以先走完,子协程依然会运行,比如:
在这个程序里面,父协程会首先打印 I am done,子协程会后打印:
即使,不使用 join 方法,也是如此。
 
Loading...
二手的程序员
二手的程序员
路漫漫其修远兮
公告
 
可以占个坑,虽然现在没人说话。
QQ群:
notion image
Telegram群:
notion image
 
我的公众号:
notion image
我的微信:
notion image