代码之家  ›  专栏  ›  技术社区  ›  Son Truong

当主线程退出时,协程会发生什么?

  •  4
  • Son Truong  · 技术社区  · 8 年前

    在Java中,当主线程退出时,所有用户线程(非deamon线程)将一直运行,直到它们完成任务为止。

    Java版本:

    fun main(args: Array<String>) {
        println("Main start")
    
        countWithThread()
    
        println("Main end")
    }
    
    fun countWithThread() {
        Thread(Runnable {
            for (i in 1..5) {
                println("${Thread.currentThread().name} count $i")
                Thread.sleep(10)
            }
        }).start()
    }
    

    输出:

    Main start
    Main end
    Thread-0 count 1
    Thread-0 count 2
    Thread-0 count 3
    Thread-0 count 4
    Thread-0 count 5
    
    Process finished with exit code 0
    

    fun main(args: Array<String>) {
        println("Main start")
    
        countWithCoroutine()
    
        println("Main end")
    }
    
    fun countWithCoroutine() {
        launch(CommonPool) {
            for (i in 1..5) {
                println("${Thread.currentThread().name} count $i")
                delay(10)
            }
        }
    }
    

    输出:

    Main start
    Main end
    
    Process finished with exit code 0
    

    如您所见,当主线程退出时,协程中的代码不再运行。看来科特林在引擎盖下终止了所有的合作。

    有人能告诉我当主线程退出时,协程到底发生了什么吗?

    2 回复  |  直到 7 年前
        1
  •  5
  •   Marko Topolnik    8 年前

    然而 它在何时允许JVM终止上有发言权。创建自己的:

    val threadPool = Executors.newFixedThreadPool(4)
    val dispatcher = threadPool.asCoroutineDispatcher()
    

    现在如果你用它来代替 CommonPool :

    launch(dispatcher) { ... }
    

    你会发现JVM并没有消亡,即使所有的任务都完成了。只有当你明确地说

    threadPool.shutdown()
    

    但请注意 executor.shutdown() 对协同程序的处理方式与对提交给它的“经典”任务的处理方式不同。执行器将确保在关闭之前完成所有提交的任务,但是它没有关于已挂起的协程的帐户。

        2
  •  2
  •   zsmb13    8 年前

    当主线程完成执行并且进程/JVM实例死亡时,协程终止,它们就像守护进程线程一样。看到了吗 this section 以供参考。