ExecutorService 的未来任务没有真正取消 [英] Future task of ExecutorService not truly cancelling

查看:21
本文介绍了ExecutorService 的未来任务没有真正取消的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

ExecutorService taskExecutor = Executors.newCachedThreadPool();映射<字符串,未来<对象>>结果 = new HashMap <String, Future<Object>>();未来<对象>future = taskExecutor.submit(new MyProcessor(uid));结果.put(uid,未来);

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

public static synchronized boolean cancelThread(String uid) {未来<对象>未来 = 结果.get(uid);布尔成功 = 假;如果(未来!= null){成功 = (future.isDone() ? true : future.cancel(true));如果(成功)结果.remove(uid);}返回成功;}

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

我哪里出错了?有没有更好的方法来做到这一点?

解决方案

我后来在 Callable 过程中遇到断点,就好像 Future cancel() 没有效果一样.

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

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

请在此处查看我的 SO 答案以获取更多详细信息:如何使用线程的 id 挂起线程?

I push my Futures from a ExecutorService into a hash map. Later, I may call cancel on Futures from within the hash map. Although the result is true, I later hit breakpoints within the Callable procedure, as if the Future cancel() had no effect. I think it might be a case of two different references here (even though the reference IDs are listed as the same when breakpointing), but was wondering if some experts could chime in. Here's what the code looks like:

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

I allow processing to continue (it's a loop that submits tasks as they are passed in), and later I may attempt to cancel from an outside source by calling this method:

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;     
}

But I still encounter a "non-cancelled" path within MyProcessor.call() after future.cancel() is called - i.e. it's not really being cancelled.

Where am I going wrong with this? Is there a better was to do this?

解决方案

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

Future.cancel(true) removes a job that is in the queue and not yet running but if the job is already running it does the equivalent of Thread.interrupt() on the thread running the job. This sets the interrupt bit on the thread and causes any sleep(), wait(), and some other methods to throw InterruptedException.

It is important to realize that it does not stop the thread. You need to actively check for the interrupt flag in your thread loop or properly handle InterruptedException.

See my SO answer here for more details: How to suspend thread using thread's id?

这篇关于ExecutorService 的未来任务没有真正取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆