2016-07-11 129 views
1

我有n个任务T1,T2,...,Tn。 我找方便的代码来完成 如下算法:执行并发任务

执行这些N个任务同时和 如果一个任务的Tx已成功完成, 停止/不执行的所有其他任务泰 - 其中y> X。

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

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

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

有什么想法?

+0

with'spring batch'你可以用async – Saravana

回答

1

您可以调用所有保留引用的期货你回来并取消它们,只要你想。

+0

来定义inter作业/任务/步骤依赖关系,希望有一些东西可以避免使用取消逻辑来“污染”任务代码,但是我认为这似乎不可行 – coder

+0

当' invokeAll'返回,所有任务已经完成。取消它们为时已晚。 – CKuck

0

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

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

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