2013-06-04 11 views
5

Ich arbeite an einem Graphen (Knoten und Vertices) Partitionierungsalgorithmus.mehrere Threads, die auf denselben Boolean schreiben

Ich verwende mehrere Threads, um bestimmte Bereiche innerhalb des Graphen zu identifizieren. Wenn ein Knoten als Teil einer Region identifiziert wurde, setze ich boolean marked für das Knotenobjekt auf true.

Mehrere Threads können versuchen, denselben Knoten zur gleichen Zeit zu markieren.

Derzeit verwende ich die Synchronisierung, um sicherzustellen, dass nichts Schlimmes passiert.

Aber seit ich nie lesen Sie den Wert von markiert, bis alle Threads die Verarbeitung abgeschlossen haben. Würde es mir möglich sein, den Synchronisationscode loszuwerden? Mit anderen Worten, kann etwas schief gehen, wenn gleichzeitig in eine boolesche Variable geschrieben wird?

+0

Ist immer auf false gesetzt markiert wenn es auf wahr gesetzt wurde? – berry120

+0

nein. nur auf wahr gesetzt –

Antwort

3

Kann irgendetwas schief gehen, wenn gleichzeitig in eine boolesche Variable geschrieben wird?

Ja und nein. Natürlich wird der resultierende Wert nicht irgendwie korrumpiert, aber es wird nicht-deterministisch sein, welches der Updates auf dem Feld gesetzt wird und wann diese Aktualisierungen von anderen Threads gesehen werden - wenn überhaupt.

Wenn Sie mehrere Threads haben, die Entscheidungen über den Wert dieses booleschen Werts treffen, müssen Sie zu einem bestimmten Zeitpunkt eine Speichersynchronisierung durchführen. Das Feld volatile kostet sehr wenig und es sei denn, Sie haben Beweise dafür, dass es sich um ein Performance-Problem handelt. Das Feld volatile ist wahrscheinlich keine vorzeitige Optimierung. Wenn Sie vergleichen und einstellen, wird ein AtomicBoolean empfohlen, der eine volatile boolean umschließt und höhere Methoden wie compareAndSet(...) bereitstellt.

0

Nein. Wenn die Reihenfolge der Schreibvorgänge für diese Variable keine Rolle spielt.

+1

Das Problem ist, dass die Schreibvorgänge * niemals * von den Leser-Threads beobachtbar sind. – assylias

+0

@assylias Auch wenn "ich den Wert von markiert nie gelesen habe, nachdem alle Threads die Verarbeitung beendet haben"? Können Sie erklären? –

+0

Die Tatsache, dass der Schreib-Thread seinen Job abgeschlossen hat, bedeutet nicht, dass die vorgenommenen Änderungen ordnungsgemäß veröffentlicht wurden und von einem anderen Thread gelesen werden können. – assylias

2

In der Theorie, nein, aber ich hätte nichts dagegen, die Variable volatile zu deklarieren. Das flüchtige Schlüsselwort gewährleistet den atomaren Zugriff.

(Vorausgesetzt, dass die Reihenfolge der Schreibvorgänge ist nicht wichtig und alle lesen, nachdem alle Schreibvorgänge auftreten.)

+2

Es geht nicht um atomaren Zugriff, der immer mit einem 'boolean' passiert, es sei denn, Sie machen einen Test permanent und setzen eine Operation, von der' volatile' Sie nicht rettet. Es geht um die Reihenfolge der Operationen und die Sichtbarkeit des Speichers. – Gray

+0

Wenn es keine korrekte Synchronisation gibt, ist es möglich, dass ein Leser-Thread "falsch" liest, obwohl ein Writer-Thread den Booleschen Wert auf "wahr" setzt. Es gibt ein Sichtbarkeitsproblem in dem, was das OP beschreibt. – assylias

2

Nein, konnte nichts mehr schief gehen, wenn mehrere Threads auf den gleichen Booleschen Wert schreiben, aber es kann ein Problem sein den Wert (auch eine lange Zeit) später in einem anderen Thread zu lesen. Sie sollten die Variablen mindestens als volatile markieren, um das Problem zu vermeiden.

1

Wie andere bereits gesagt haben, besteht keine Gefahr von Korruption oder falschen Werten für den Booleschen Wert, wenn Sie einfach versuchen, denselben Wert aus mehreren Threads festzulegen.

jedoch können Sie nicht einmal brauchen, dass

ich nie den Wert der markiert, bis schließlich die Fäden Verarbeitung fertig gelesen.

Sie offensichtlich eine Art Barriere müssen die koordinierende Gewinde mit den Worker-Threads (wie Thread.join() oder CountdownLatch oder Ihre primitive du jour) und fast alle jene bereits bieten ein geschieht zuvor Beziehung zu synchronisieren, wird Machen Sie alle Ihre Markierungen für den Coordinator-Thread sichtbar.

Nachdem die einzelne Synchronisationspunkt auch nur zufällig billiger sein als eine große Anzahl von flüchtigen Lesen (und ich würde diese vorzeitige Optimierung nicht nennen, einfach die Notwendigkeit für flüchtige Stoffe eliding)

+0

danke .. das macht Sinn. (Ich benutzte thread.join()) zusammen mit volatilen booleans.Ich werde booleans anstelle von volatile booleans verwenden –

Verwandte Themen