ExecutorService的未来任务并未真正取消

Rya*_*n H 11 java concurrency future executorservice

我将Futures从ExecutorService推送到哈希映射中.之后,我可以在哈希映射中调用取消期货.虽然结果是正确的,但我后来在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);
Run Code Online (Sandbox Code Playgroud)

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

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;     
}
Run Code Online (Sandbox Code Playgroud)

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

我哪里错了?这样做有好处吗?

Gra*_*ray 17

我后来在Callable过程中命中了断点,好像Future cancel()没有效果.

Future.cancel(true)删除队列中尚未运行的作业,但如果作业已在运行,则执行相当于的操作Thread.interrupt().这台线程上的中断位并使所有sleep(),wait()以及其他一些方法抛出InterruptedException.

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

有关详细信息,请参阅我的答案:

如何使用线程的id挂起线程?