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()