问题描述
我有一个简单的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
并始终使用由提供的执行程序。 runBlocking
或DefaultDelay
(后退delay
)。
为确保检查协同程序中的Thread.currentThread()
,以查看代码当前在何处执行。