9

Frage ich für Jahre gehabt haben: In diesem Pseudo-Code,Stellt .awaitTermination() vor, was im Executor ausgeführt wird?

ExecutorService svc = Executors.newFixedThreadPool(3); 
svc.submit(new Runnable() { /* code A */ }); 
svc.shutdown(); 
if(svc.awaitTermination(...)) { 
    // code B 

.awaitTermination() ist zwischen Code A & B. nicht dokumentiert als Gründung vor-geschieht Gibt es einen Grund, warum es nicht ist?

Das ExecutorService und concurrent package javadocs definiert passiert-vor zwischen den Aufgaben und Arbeit vor sie eingereicht wurden, aber nicht zwischen Testamentsvollstrecker Aufgaben und Code nach einem erfolgreichen .awaitTermination() Anruf.

Hinweis, ich frage nicht nach Design-Kritik, wie ich meinen Code restrukturieren kann, um dokumentierte Vorkommnisse zu nutzen. Meine Frage hier ist, gibt es einen Grund, den die Ärzte nicht erwähnen, passiert in dieser Situation?

(Beachten Sie, dass dies nicht ein Duplikat 22665198 trotz des sehr passender Titel.)

+0

Logik diktiert, dass es eine Vorbestellung geben sollte, aber Sie haben Recht OP, ich kann es nirgendwo dokumentiert finden. –

+1

Die einzige "offizielle" Garantie ist, dass wenn Sie die Zukunft mit 'Future f = svc.submit (...)' UND Sie rufen 'f.get()', dann haben Sie Ihre hb-Beziehung. – assylias

+0

@assylias also, warum ist das? Muss ich wirklich jede Aufgabe ".get()"? Ich weiß, dass ich viel Code geschrieben habe, der davon ausgeht, dass eine erfolgreiche '.awaitTermination()' eingerichtet * passiert-vor *. – tariksbl

Antwort

1

ExecutionService, sind Sie sicher? Meinst Du ExecutorService? Auch gibt es keine ExecutorService.awaitTermination() Methode ohne Parameter. Die Methode ExecutorService.awaitTermination(long, TimeUnit) empfängt die Wartezeit bis zum Timeout. Offensichtlich kann es, wenn es wegen der Zeitüberschreitung zurückkehrt, die "happen-before" -Beziehung nicht garantieren, daher kann es diese Garantie in seinem Vertrag nicht ankündigen, weil es nicht für alle Fälle da ist.

+3

Warum können die Javadocs nicht sagen * Wenn dieser Aufruf normal zurückkehrt, wird eine Vorbestellung * durchgeführt. –

+0

Mein Pseudocode behoben, danke. – tariksbl

+0

@JohnVint Weil diese Information nutzlos wäre, da sie nur zur Laufzeit bekannt wäre.Sie müssen sich auf diese Reihenfolge verlassen, um den richtigen Code zu schreiben. –

-1

Eigentlich sind Sie falsch, wie es

Blocks dokumentiert, bis alle Aufgaben Ausführung nach> einen Shutdown-Anforderung abgeschlossen haben, oder das Timeout auftritt, oder> die aktuelle Thread unterbrochen wird, je nachdem, was zuerst eintritt.

Es ist also garantiert, dass entweder eine Aufgabe abgeschlossen wird oder eine Zeitüberschreitung auftritt. Die Sache ist, dass wir nur diese Situationen unterscheiden müssen, indem wir den Rückgabewert der Methode überprüfen. Es wird wahr sein, wenn Aufgaben abgeschlossen sind. Falsch bei Timeout oder Unterbrechung.

+0

Speicherkonsistenz ist anders - siehe https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html – tariksbl

+0

In dieser Situation überhaupt nicht verwandt. Es gibt keine Wettlaufbedingungen zwischen Arbeiterfäden und Fäden von außerhalb des Pools, die auf seine Beendigung warten. – Antoniossss

+1

@Antoniossss Worker-Threads und Outside-Threads teilen denselben Speicher. Wie können Sie sicher sein, dass es keine Race Conditions gibt? Angenommen, einer der Worker schreibt einen Wert in ein statisches Feld und der äußere Thread versucht, ihn zu lesen, nachdem 'awaistTermination'' true' zurückgibt. Was sind die Garantien, dass der äußere Thread beobachten wird, dass schreiben, wenn passiert, bevor es nicht durchgesetzt wird? –

Verwandte Themen