并发任务执行

时间:2016-07-11 09:33:38

标签: java concurrency

我有n个任务T1,T2,...,Tn。 我正在寻找方便代码来完成 以下算法:

同时执行这n个任务 如果任务Tx已成功完成, 停止/不执行所有其他任务Ty其中y> X。

这里成功意味着找到解决方案, 并非所有任务都能找到解决方案。

使用ExecutorService.invokeAll并不是那么好, 因为所有线程都在运行直到完成。

ExecutorService.invokeAny不起作用,因为 完成任务x并不是保证 首先是最小的x。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您可以调用所有参考资料保留您获得的期货,并随时取消它们。

答案 1 :(得分:0)

您可以使用线程来执行这些任务,您需要将这些线程存储在List中,然后一旦线程完成(成功)就可以使用循环运行所有线程,您将使用线程列表来停止其他

public class Task implements Runnable {
    private MainThread mainThread;
    @Override
    public void run() {
       while(true){
        // do something
       if(success) {
           // may be it will be usefull if you inject the success thread in the stop process method (to know which thread has done the task)
           mainThread.stopProcess(this);
           break;
        }
       // this condition will stop the thread 
       if (Thread.currentThread().isInterrupted()) {
       // cleanup and stop execution
       // for example a break in a loop
       break;
       }      
    }
   }
}

在主线程类中,您将管理线程(任务)

public class MainThread {
   public boolean stopProcess = false;
   public List<Thread> processors;
   // add constructor with some initialization logic for processors list, inject in each processor the main Thread class (this)

   public void process(){
      for(Thread process : processors){
        process.start();
      }
   }

   public synchronized stopProcess(Runnable task){
       if(!stopProcess){
         stopProcess = true;
         for(Thread process : processors){
           process.interrupt();
         }
      }
   }

}

答案 2 :(得分:0)

这应该可以解决问题:

T invoke(List<Callable<T>> tasks) throws InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(tasks.size());

    List<Future<T>> futures = tasks.stream()
                                   .map(executorService::submit)
                                   .collect(toList());
    T result = null;
    for (Future<T> future : futures)
        if (result == null)
            try { result = future.get(); }
            catch (ExecutionException e) { }
        else
            future.cancel(true);

    return result;
}