2016-07-11 10 views
1

Ich habe n Aufgaben T1, T2, ..., Tn. Ich suche Bequemlichkeit Code den folgenden Algorithmus zu erreichen:Concurrent Aufgaben Ausführung

diese n Aufgaben ausführen gleichzeitig und , wenn eine Aufgabe Tx erfolgreich abgeschlossen wurde, stop/nicht ausführen alle anderen Aufgaben Ty wo y> x.

Erfolgreich bedeutet hier, eine Lösung zu finden, nicht alle Aufgaben werden eine Lösung finden.

Verwenden von ExecutorService.invokeAll ist nicht so gut, , da alle Threads bis zur Fertigstellung ausgeführt werden.

ExecutorService.invokeAny funktioniert nicht, weil es nicht garantiert ist, dass die Aufgabe x, die zuerst beendet, das kleinste x ist.

Irgendeine Idee?

+0

mit 'Spring Batch' können Sie Inter Job/Task/Schritt Abhängigkeiten mit async – Saravana

Antwort

1

Sie können alle Referenzen auf die Futures, die Sie erhalten, zurückrufen und sie jederzeit abbrechen.

+0

hoffe, es gibt etwas zu vermeiden "Verschmutzung" der Task-Code mit Stornierungslogik, aber je mehr denke ich, dass dies nicht möglich scheint – coder

+0

When ' "invokeAll" gibt zurück, alle Aufgaben sind bereits beendet. Es ist zu spät, sie abzusagen. – CKuck

0

Sie können Threads verwenden, um diese Aufgaben auszuführen, müssen Sie diese Threads in einer Liste speichern, dann können Sie alle mit einer Schleife ausführen, sobald ein Thread beendet ist (erfolgreich) werden Sie die Thread-Liste zum Anhalten verwenden die anderen

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 Ihrem Haupt-Thread-Klasse werden Sie Ihre Threads (Aufgaben) verwalten

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

Diese den Trick tun sollten:

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