java - ExecutorService 的 future 任务并未真正取消

标签 java concurrency executorservice future

我将我的 Futures 从 ExecutorService 推送到 HashMap 中。稍后,我可能会从 HashMap 中调用 Futures 上的取消。尽管结果为真,但我后来在 Callable 过程中遇到了断点,就好像 Future cancel() 没有效果一样。我认为这可能是两个不同引用的情况(即使在断点时引用 ID 被列为相同),但想知道是否有专家可以插话。代码如下所示:

ExecutorService taskExecutor = Executors.newCachedThreadPool();
Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();      

Future<Object> future = taskExecutor.submit(new MyProcessor(uid));
results.put(uid, future);

我允许处理继续(这是一个在任务传入时提交任务的循环),稍后我可能会尝试通过调用此方法从外部源取消:

public static synchronized boolean cancelThread(String uid) {
    Future<Object> future = results.get(uid);
    boolean success = false;
    if (future != null) {
        success = (future.isDone() ? true : future.cancel(true));
        if (success)
            results.remove(uid);
    }
    return success;     
}

但在调用 future.cancel() 之后,我仍然在 MyProcessor.call() 中遇到“未取消”路径 - 即它并没有真正被取消。

我哪里出错了?这样做有更好的办法吗?

最佳答案

I later hit breakpoints within the Callable procedure, as if the Future cancel() had no effect.

Future.cancel(true) 删除队列中尚未运行的作业,但如果该作业已经在运行,则它的作用相当于 Thread.interrupt() 在运行作业的线程上。这会在线程上设置中断位并导致任何 sleep()wait() 和一些其他方法抛出 InterruptedException

重要的是要认识到它不会停止线程。您需要主动检查线程循环中的中断标志或正确处理 InterruptedException

请在此处查看我的 SO 答案以获取更多详细信息:How to suspend thread using thread's id?

关于java - ExecutorService 的 future 任务并未真正取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11158454/

相关文章:

javascript - JS如何既是非阻塞/异步又是单线程的?

java - 500个Worker Threads,什么样的线程池?

java - 可调用任务未正确执行

java - Servlet 只为每个访问者启动一次线程

java - 读写锁

java - Spring jpa实体和Lombok

python - 为什么我看到 Python BaseHTTPServer 出现随机读取错误?

java - 如何合并从执行者 Future 返回的 Multimaps 列表与 Java8

java - 内存映射文件 java NIO

java - java 和 servlet 的类路径