coder
coder

Reputation: 1445

Concurrent tasks execution

I have n tasks T1, T2, ... , Tn. I am looking for convenience code to accomplish the following algorithm:

Execute these n tasks concurrently and if a task Tx has completed successfully, stop/don't execute all other tasks Ty where y > x.

Successfully here means finding a solution, not all tasks will find a solution.

Using ExecutorService.invokeAll isn't that good, because all threads are running until completion.

ExecutorService.invokeAny doesn't work because it isn't guarenteed that the task x which finished first is the smallest x.

Any idea?

Upvotes: 1

Views: 204

Answers (3)

CKuck
CKuck

Reputation: 712

This should do the trick:

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

Upvotes: 0

Anas EL KORCHI
Anas EL KORCHI

Reputation: 2058

You can use threads to execute those tasks, you will need to store those threads in a List then you can run all of them with a loop once a thread is finished (successfully) you will use the list of thread to stop the others

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

In your main thread class you will manage your threads (tasks)

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

}

Upvotes: 0

M. McLean
M. McLean

Reputation: 84

You can invokeAll keep the references the the Futures you get back and cancel them whenever you want.

Upvotes: 1

Related Questions