Thread Join () wartet nicht

7

Ich versuche, über Threads zu lernen, und ich verstehe die Methode join() nicht.

Ich habe einen Thread (ThreadAdd.java), der 1 zu einem statischen int hinzufügt.

%Vor%

In meiner main Methode starte ich 2 Threads:

%Vor%

Ich verstehe nicht, warum das Ergebnis meistens 2 ist, aber manchmal gibt es 1 zurück.

    
damien marchand 21.02.2015, 12:02
quelle

5 Antworten

11

Der Grund, warum Sie 1 manchmal sehen, ist nicht, weil join() nicht auf das Ende des Threads warten kann, sondern weil beide Threads versuchten, den Wert gleichzeitig zu ändern. Wenn dies geschieht, können unerwartete Ergebnisse auftreten: Wenn beispielsweise beide Threads versuchen, count zu erhöhen, was null ist, könnten beide null lesen und dann 1 hinzufügen und das Ergebnis speichern. Beide speichern das gleiche genaue Ergebnis, d. H. 1, so dass Sie es sehen werden, egal wie lange Sie warten.

Um dieses Problem zu beheben, fügen Sie synchronized um das Inkrement hinzu oder verwenden Sie AtomicInteger :

%Vor%     
dasblinkenlight 21.02.2015, 12:06
quelle
4

Die Methode join ist hier nicht das eigentliche Problem. Das Problem besteht darin, dass Ihr Zähler nicht für die Synchronisierung von Thread-Threads vorbereitet ist, was dazu führen kann, dass jeder Thread einen anderen Wert in count beobachtet.

Es wird dringend empfohlen, einige Themen der gleichzeitigen Programmierung zu studieren, einschließlich der Behandlung in Java.

    
E_net4 21.02.2015 12:07
quelle
4

Weil Sie das Inkrement der Ganzzahl count nicht synchronisieren. Die beiden Threads können verschachtelt werden, während die Variable inkrementiert wird.

Siehe Ссылка für eine Erläuterung. Das Beispiel in der Verknüpfung ähnelt Ihrem Beispiel und es wurde eine Lösung bereitgestellt, um diese Thread-Interferenz zu vermeiden ist die Verwendung atomarer Variablen wie java.util.concurrent.atomic.AtomicInteger .

    
manouti 21.02.2015 12:06
quelle
2

Ihre count -Variable ist nicht volatile . Daher müssen Threads ihren Wert nicht jedes Mal überprüfen. Gelegentlich verursacht die Befehlsreihenfolge Fehler wie diese.

Da count++ jedoch syntaktischer Zucker für count = count + 1 ist, wird sogar die Variable volatile nicht sicherstellen, dass Sie das Problem nicht haben, da zwischen dem Read und dem anschließendes Schreiben.

Um Code wie diesen sicher zu machen, verwenden Sie stattdessen AtomicInteger .

    
chrylis 21.02.2015 12:08
quelle
2

Das hat nichts mit join zu tun. Der Thread, der mit join() wartet, ist Ihr main -Thread. Die beiden anderen Threads warten auf nichts. Und das join veranlasst sie nicht, etwas anders zu machen.

Und wie die anderen Antworten sagen, schreiben die zwei Threads gleichzeitig auf die gleiche Variable, und deshalb erhalten Sie das Ergebnis, das Sie sehen.

Vielleicht haben Sie erwartet, dass join() einen der Threads verzögert, so dass es nicht gleichzeitig mit dem anderen funktioniert, aber so funktioniert es nicht. Der einzige Thread, der verzögert wird, ist der -Aufrufer von join() , nicht der Zielthread.

    
RealSkeptic 21.02.2015 12:10
quelle

Tags und Links