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

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

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

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

谢谢。

【问题讨论】:

  • 有解决问题的办法吗?
  • 答案可能在您的标签中:)

标签: java multithreading executorservice producer-consumer


【解决方案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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 2011-06-23
    • 2014-02-25
    • 2021-04-11
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多