协程即使在其线程关闭后也可以在调度程序上运行

问题描述

我有一个简单的Kotlin程序,它用一个线程创建了一个执行程序,并将其用作协程调度程序。

当我关闭执行程序线程时,我期望协程不会运行(或引发异常),因为线程已终止,但这不是对runMethod(singleThread)的第二个方法调用中发生的事情:

fun main(args: Array<String>) {
    val singleThread = Executors.newSingleThreadExecutor()

    runMethod(singleThread)
    singleThread.shutdownNow()
    runBlocking {
        delay(100)
    }
    println("Shutdown status: ${singleThread.isShutdown},terminated status: ${singleThread.isTerminated}")
    runMethod(singleThread)

    println("Program ended")
}

fun runMethod(executor: ExecutorService) {
    runBlocking {
        launch(context = executor.asCoroutineDispatcher()) {
            for (i in 1..10) {
                print("$i ")
                delay(10)
            }
        }
    }
    println("\nEnd")
}

以下是该程序的输出:

1 2 3 4 5 6 7 8 9 10 
End
Shutdown status: true,terminated status: true
1 2 3 4 5 6 7 8 9 10 
End
Program ended

Process finished with exit code 0

解决方法

如果我不得不猜测这可能是一个事实,那就是所使用的唯一挂起函数是delay。由于Executors.newSingleThreadExecutor()不是ScheduledExecutorService,因此它必须依靠后备机制来调度延迟调用,这可能导致它从不实际使用提供的Executor并始终使用由提供的执行程序。 runBlockingDefaultDelay(后退delay)。

为确保检查协同程序中的Thread.currentThread(),以查看代码当前在何处执行。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...