2014-03-26 12 views
5

Bitte helfen Sie zu verstehen, ExecutorService # awaiteTermination (Timeout) Verhalten.Ist awaistTermination in ExecutorService "passiert vor" irgendeinen Code, der danach ausgeführt wird?

Ich beobachte Situation, wenn ich in meinem Code haben:

private void shutdownAndAwaitTermination(ExecutorService threadPool){ 
    threadPool.shutdown(); 
    try { 
     if (!threadPool.awaitTermination(threadPoolTimeout, TimeUnit.HOURS)){ 
      threadPool.shutdownNow(); 
      if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) { 
       logger.warn("Pool did not terminate"); 
      } 
     } 
    } 
    catch (InterruptedException ie)  { 
     threadPool.shutdownNow(); 
     Thread.currentThread().interrupt(); 
    } 
} 

Ist der Pool in Aufgaben vollständig in diesem Fall vor alle anderen Anrufe nach shutdownAndAwaitTermination() in demselben Thread?

Blick in dem, was auf der Produktion geschieht, glaube ich, dass die Antwort keine, aber ich möchte nur wissen, wie sicher zu stellen, dass jeder Code nach einem Aufruf von shutdownAndAwaitTermination platziert() wird nach letzter Aufgabe passiert in Pool wird vervollständigt.

Danke.

Antwort

1

Nein, die Aufgaben könnten definitiv abgeschlossen werden, nachdem Sie von Ihrer shutdownAndAwaitTermination() Methode zurückgekehrt sind, weil Sie eigentlich keine Kündigung erwarten. Wenn der wartende Thread unterbrochen wird oder zu lange dauert, hören Sie auf zu warten, obwohl die Aufgaben möglicherweise noch ausgeführt werden.

Auch wenn Sie shutdownNow() anrufen, reagieren Ihre Aufgaben möglicherweise nicht auf Unterbrechung (und im Allgemeinen wird ExecutorService nicht garantiert, Unterbrechung zu verwenden). So können Aufgaben möglicherweise noch ausgeführt werden.

Wenn Sie Aufgabenerledigung sicherstellen wollen, geschieht zuvor von dieser Methode zurückkehrt, müssen Sie bis awaitTermination() kehrt immer wieder versuchen, true, trotz Unterbrechungen, etc. Das ist ein schlechtes Design wäre, so wäre es besser, Wenn Ihre Aufgaben ihre Ergebnisse über eine Future zurückgegeben, anstatt Nebenwirkungen nicht atomar zu produzieren. Auf diese Weise können Aufgaben, die erfolgreich abgeschlossen wurden, ausgeführt werden, während Aufgaben, die nicht abgeschlossen wurden, ignoriert werden können.

+0

Ich glaube, ich muss threadPool.invokeAll (...) verwenden, um sicherzustellen, dass alle Aufgaben abgeschlossen sind. Erstellt invokeAll() happes-before? –

+0

@MaximGalushka Ja, wenn 'invokeAll()' ohne Ausnahme zurückgibt, wird die gesamte Aufgabenbeendigung 'vor-before' ausgeführt. – erickson

+0

Dank @erickson werde ich das tun. –

0

von http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html:

List<Runnable> shutdownNow 
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, 
and returns a list of the tasks that were awaiting execution. 
This method does not wait for actively executing tasks to terminate. 
Use awaitTermination to do that. 

Es gibt keine Möglichkeit, genau zu stoppen Faden, so dass Sie für bereits laufende Aufgaben warten, zu beenden.