coroutineScope 下的线程不会停止
Thread underneath coroutineScope does not stop
我在停止协程线程时遇到问题。我对协程没有很深的了解,如果我有任何错误,请纠正我,但我无法在任何地方找到解决方案。
我面临的问题是,当我调用 coroutineScope.cancel()
它不会停止下面的线程,协程正在停止并且它不会继续运行但是下面的线程移动到 WAITING
状态。
我启动协程的方式 ->
scope = CoroutineScope(
newFixedThreadPoolContext(
request.size,
"Sync Proxy connection threads dispatcher"
)
)
在启动过程中,我将 Job 保存在 ConcurrentHashMap ->
request.forEach {
jobs[it] = (scope.launch {
runConnectorProcess(it)
})
}
然后根据一些逻辑我调用取消 ->
jobs[request]?.let {
it.cancel()
jobs.remove(syncRequest)
}
如果它是最后一个被取消的元素 -> scope.cancel()
在调试过程中,我在线程转储中发现该线程的状态为 WAITING
来自 VisualVM 的日志 ->
"Sync Proxy connection threads dispatcher" #168 daemon prio=5 os_prio=31 tid=0x00007fa78281b800 nid=0xd42f waiting on condition [0x000000030f563000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000077b305878> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2044)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
您不应期望取消 CoroutineScope 也会关闭它引用的 CoroutineDispatcher,因为该范围不拥有调度程序。调度程序可以由多个范围和单个协程使用。毕竟,它只是传递给 CoroutineScope 构造函数的参数。如果你想关闭你的 CoroutineDispatcher,你需要将它存储在它自己的 属性 中,这样你就可以在需要的时候调用它 close()
。
我在停止协程线程时遇到问题。我对协程没有很深的了解,如果我有任何错误,请纠正我,但我无法在任何地方找到解决方案。
我面临的问题是,当我调用 coroutineScope.cancel()
它不会停止下面的线程,协程正在停止并且它不会继续运行但是下面的线程移动到 WAITING
状态。
我启动协程的方式 ->
scope = CoroutineScope(
newFixedThreadPoolContext(
request.size,
"Sync Proxy connection threads dispatcher"
)
)
在启动过程中,我将 Job 保存在 ConcurrentHashMap ->
request.forEach {
jobs[it] = (scope.launch {
runConnectorProcess(it)
})
}
然后根据一些逻辑我调用取消 ->
jobs[request]?.let {
it.cancel()
jobs.remove(syncRequest)
}
如果它是最后一个被取消的元素 -> scope.cancel()
在调试过程中,我在线程转储中发现该线程的状态为 WAITING
来自 VisualVM 的日志 ->
"Sync Proxy connection threads dispatcher" #168 daemon prio=5 os_prio=31 tid=0x00007fa78281b800 nid=0xd42f waiting on condition [0x000000030f563000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000077b305878> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2044)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
您不应期望取消 CoroutineScope 也会关闭它引用的 CoroutineDispatcher,因为该范围不拥有调度程序。调度程序可以由多个范围和单个协程使用。毕竟,它只是传递给 CoroutineScope 构造函数的参数。如果你想关闭你的 CoroutineDispatcher,你需要将它存储在它自己的 属性 中,这样你就可以在需要的时候调用它 close()
。