执行者取消挂起的任务 - 需要帮助

Posted

技术标签:

【中文标题】执行者取消挂起的任务 - 需要帮助【英文标题】:executor cancel pending task - help needed 【发布时间】:2013-12-26 06:25:26 【问题描述】:

基本上,我需要一台具有以下功能的机器:

    用于运行任务的固定大小的线程池 待处理任务队列(已请求,但尚未运行) 取消挂起队列中的任务(任务由 id 标识) 取消正在进行的任务 给定任务 id,查询任务是 Pending 还是 Running

任何人都可以提出实现这一目标的最佳方法,尤其是第 3-5 项。我真的很感激一些代码示例。

谢谢。

【问题讨论】:

有解决问题的办法吗? 答案可能在您的标签中:) 【参考方案1】:

除了任务状态和取消之外的所有内容都是线程池的标准。取消和状态状态可以通过以下方式完成:

enum TaskState PENDING, RUNNING;

abstract class MyCallable<V> implements Callable<V>
    protected volatile TaskState state = PENDING;

    // to make sure state is always set before running the task
    protected abstract V doCall();

    final V call()
        state = RUNNING;
        return doCall();
    

    public TaskState getState()  return state; 


...

ExecutorService executor = Executors.newFixedThreadPool(4);

Future<V> future = executor.submit(new MyCallable<V>() 
    public V doCall() throws Exception 
        //... some work ...
        if(Thread.interrupted())
            removeFromMap();
            return null;
        
    
);

...

future.cancel(true);

要使任务可取消,需要在其执行期间检查Thread.interrupted() 状态或其他逻辑布尔标志。在获得提交任务的未来后,应调用future.cancel(true) 以通过中断来取消任务。

【讨论】:

非常感谢。几个问题: 1. 我想在executor.submit 之后我还需要做类似pendingMap.put(id, future); 的操作并从MyCallable.call 中的地图中删除项目,因为我需要通过id 取消 2. 你强烈推荐使用Callable 吗?我在想Runnable,因为我不需要返回值 3。ThreadPool 由 android 服务管理。处理完所有任务后,我需要停止服务。检测方法是什么? 1.只需使用ConcurrentHashMap 并删除对中断(从内部)或取消(从任务外部)进行的正面测试。 2.Runnable 没问题 3.executor.shutdown(); executor.awaitTermination(); 第一个命令停止接受进一步的作业,第二个等待所有正在运行的作业终止。希望这会有所帮助! 谢谢。关于3.我的意思实际上不同:我确实想继续提交任务,但是当一切都处理完后,我需要停止服务。所以我想正确的方法是:在每个任务结束时检查 hashMap 是否为空(没有正在运行/排队的任务),如果是 -> 停止服务。我认为这应该可行。 我认为这应该可行。您可能需要在运行一次的单独线程中等待终止。 啊,你的最后一句话看起来比检查未来的 hashMap 是否为空更优雅:所以,你建议只使用一个专用的new Thread() void run() executor.awaitTermination(); [service.]stopSelf(); 我的理解正确吗?这是一种常见的做法吗?【参考方案2】:

您需要的一切都在标签中。如果使用固定线程池ExecutorService,可以限制可以同时执行的线程数。

如果提交的线程数超过了可以处理的数量,它们将被保存在队列中。

调用 ExecutorService 的 submit() 方法会给你一个 Future 对象,它会让你知道任务是挂起还是被取消等等

我确实有一系列关于ExecutorService的教程:http://codelatte.wordpress.com/2013/11/09/a-simple-newfixedthreadpool-example/

Future 对象使用方法:http://codelatte.wordpress.com/2013/11/08/a-simple-cachedthreadpool-example/

【讨论】:

以上是关于执行者取消挂起的任务 - 需要帮助的主要内容,如果未能解决你的问题,请参考以下文章

ThreadPoolExecutor : 拉出挂起的任务

ThreadPoolExecutor:拉出挂起的任务

如何检测 Ansible playbook 在执行期间挂起的原因

linux系统中挂起操作和强制结束操作(后台运行程序方法)

如何在 Angular 4+ 中取消/取消订阅所有挂起的 HTTP 请求

vs2013-执行签入挂起的更改,提示没有挂起的更改(实际代码已修改)