加快散乱的幂等任务

时间:2009-06-10 09:19:03

标签: java multithreading concurrency

我正在运行多个幂等任务来收集一批数据。我发现很多次计算由于一百个任务中的几个任务而显着延迟。

我想要的是一种观察这些任务的方法,如果它们被显着延迟,则再次启动落后者。

在Java中是否有标准库或习惯用法?我目前正在使用ExecutorService / ExecutorCompletionService对来完成工作。

2 个答案:

答案 0 :(得分:2)

如果您有权访问代表此任务的Future对象,则可以根据需要检查isDone()cancel()。您必须轮询这些未来的对象并相应地重新提交。它还取决于适当处理InterruptExceptions的基础Runnables

答案 1 :(得分:1)

您可以创建一种任务管理器,其中包含对每个任务的引用。此任务管理器可以负责启动每个任务和管理ExecutorService。每项任务的第一项和最后一项操作是向经理注册任务的开始和结束。然后,经理可以建立统计图片,该图片是执行每项任务所花费的时间的平均值。

任务管理器定期扫描其正在运行的任务列表,查找仍在运行的“异常值”,并且从特定任务的平均时间开始漂移很多。然后它可以取消这些任务并重新启动它们。

下面是你可以做的一个非常粗略的概述...

public class Task implements Runnable {
     protected TaskManager manager_ = null;
     protected String taskClass_ = null;
     protected String taskId_ = null;

     protected Task(TaskManager manager, String taskClass) {
        manager_ = manager;
        taskClass_ = taskClass;
     }

     /*
      * Override this and perform specific task.
      */
     protected void perform() { }

     public void run() {
      try {
          manager_.taskStarted(this);
          perform();
          manager_.taskCompleted(this);
      catch(InterruptedException) {
          manager_.taskAborted(this);
      }
      finally {
      }
    }
}


public class TaskManager {
    ExecutorService service_ = null;

    public TaskManager() {
       service_ = new ExecutorService();
       // start the monitoring thread.
       service_.execute(this);
    }

    public void runTask(Task t) {
       service_.execute(t);
    }

    public void taskStarted(Task t) {

        1. Note the time that this task (with unique id) has started.
        2. Add time to a hash map.
        3. Add task to list of executing tasks.
    }

    public void taskComplete(Task t) {
        1. Find the task id in hash map
        2. note how long it took to execute.
        3. modify statistics of how long the task took against
           the task Class Id.
        4. Remove task from list of executing tasks.
    }

    public void taskAborted(Task t) {
      // just remove the task from list of running tasks 
      // without altering the statistics.
    }
    public void run() {
         1. Go though the list of executing tasks looking for 
            tasks whose current time  - start time is outside the
            time statistics for the task class id.
         2. cancel the task and start again.
    }
}