9.5 协程 vs 守护线程

在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。

所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。

我们来看一段Thread的守护线程的代码:

1. fun testDaemon2() {
2. val t = Thread({
3. repeat(100) { i ->
4. println("I'm sleeping $i ...")
5. Thread.sleep(500L)
6. }
7. })
8. t.isDaemon = true // 必须在启动线程前调用,否则会报错:Exception in thread "main" java.lang.IllegalThreadStateException
9. t.start()
10. Thread.sleep(2000L) // just quit after delay
11. }

这段代码启动一个线程,并设置为守护线程。线程内部是间隔500ms 重复打印100次输出。外部主线程睡眠2s。

运行这段代码,将会输出:

1. I'm sleeping 0 ...
2. I'm sleeping 1 ...
3. I'm sleeping 2 ...
4. I'm sleeping 3 ...

协程跟守护线程很像,用协程来写上面的逻辑,代码如下:

1. fun testDaemon1() = runBlocking {
2. launch(CommonPool) {
3. repeat(100) { i ->
4. println("I'm sleeping $i ...")
5. delay(500L)
6. }
7. }
8. delay(2000L) // just quit after delay
9. }

运行这段代码,我们发现也输出:

1. I'm sleeping 0 ...
2. I'm sleeping 1 ...
3. I'm sleeping 2 ...
4. I'm sleeping 3 ...

我们可以看出,活动的协程不会使进程保持活动状态。它们的行为就像守护程序线程。