协程即使在其线程关闭后仍会在调度程序上运行
Coroutine runs on a dispatcher even after its thread is shutdown
我有一个简单的 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()
以查看代码当前正在执行的位置。
我有一个简单的 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()
以查看代码当前正在执行的位置。