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 ...

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