Thread - Methoden synchronized deklarieren

frager2345

Aktives Mitglied
Hi, also ich habe noch nicht ganz verstanden was ganz genau synchronized macht. Also klar ist, dass eine synchronized Methode nur ein Thread ausführen kann , andere Threads müssen warten bis die Methode freigegeben wird. Jedoch versteh ich z.B in diesem Beispiel wenn man erreichen will, dass nur die Ausgabe -9 möglich ist , dass man dann die Methoden synchronized deklariert. Würde es nicht auch einfach reichen die beiden Threads mit join dem main thread vorzuziehen?
Java:
public class IntValue {
    public int value = 0;
    public void inc() {
        value += 1;
    }
    public void dec() {
        value -= 10;
    }
    public void print() {
        System.out.print(value);
    }
}
public class Thread1 extends Thread {
    private IntValue iv;
    public Thread1(IntValue iv) {
        this.iv = iv;
    }
    public void run() {
        iv.inc();
    }
}
public class Thread2 extends Thread {
    private IntValue iv;
    public Thread2(IntValue iv) {
        this.iv = iv;
    }
    public void run() {
        iv.dec();
    }
}
public static void main(String[] args) {
    IntValue v = new IntValue();
    Thread1 t1 = new Thread1(v);
    Thread2 t2 = new Thread2(v); t1.start();
    t2.start();
    v.print();
}
 

httpdigest

Top Contributor
1. Das join musst du hier vor v.print(); sowieso machen, um sicherzustellen, dass die Threads fertig werden bevor du den Wert ausgibst.
2. Die Operationen value += 1; und value -= 10; sind nicht atomar. Das heißt, sie bestehen eigentlich aus mehreren Einzeloperationen, die für sich gesehen alle unterbrechbar sind.
Also: i += v; ist:
Code:
int tmp = i;
i = tmp + v;
Die Variable tmp dient hier zur "Operationalisierung" in Form von Java-Code, was tatsächlich passiert. Zwischen den beiden Operationen kann ja schon ein anderer Thread zwischenfunken und i bereits auf einen anderen Wert setzen, als wir in tmp dachten.

Und ein public synchronized void m() {...} ist quasi dasselbe wie public void m() { synchronized (this) { ... } }.
Es wird also auf this synchronisiert, so dass kein anderer Thread gleichzeitig auf this synchronisieren (i.e. "Den Monitor bekommen") kann.
Das kann natürlich über mehrere Codestellen bzw. Methoden sich erstrecken.
 

KonradN

Super-Moderator
Mitarbeiter
Ein Problem hier kann tatsächlich sein, dass die Ausgabe nicht wartet, bis die Threads fertig sind. Das wäre synchronized auch nicht zwingend ausreichend, denn es mag ja passieren, dass ein Thread angestartet wurde aber der Aufruf noch nicht gestartet wurde. Dann wäre das print vor dem inc oder dev aufgerufen worden.

Das Synchronized behebt aber ein anderes Problem:

Die Zeile value += 1 ist nicht atomar. Es wird also gemacht:
Der Wert value wird gelesen.
Dann wird diesem gelesenen Wert 1 hinzu addiert.
Das Ergebnis wird in value gelesen.

Beim anderen wäre es ähnlich - nur eben würde 10 abgezogen.

Was also nun bei zwei Threads passieren könnte:
Thread1: value wird gelesen (0)
Thread2: value wird gelesen (0)
Thread1: addiert 1 zur 0 (1)
Thread1: Schreibt die 1 zurück
Thread2 zieht 10 ab (0-10 = -10)
Thread2 schreibt die -10
==> Das Ergebnis -10 hat man nun.
 

frager2345

Aktives Mitglied
1. Das join musst du hier vor v.print(); sowieso machen, um sicherzustellen, dass die Threads fertig werden bevor du den Wert ausgibst.
2. Die Operationen value += 1; und value -= 10; sind nicht atomar. Das heißt, sie bestehen eigentlich aus mehreren Einzeloperationen, die für sich gesehen alle unterbrechbar sind.
Also: i += v; ist:
Code:
int tmp = i;
i = tmp + v;
Die Variable tmp dient hier zur "Operationalisierung" in Form von Java-Code, was tatsächlich passiert. Zwischen den beiden Operationen kann ja schon ein anderer Thread zwischenfunken und i bereits auf einen anderen Wert setzen, als wir in tmp dachten.

Und ein public synchronized void m() {...} ist quasi dasselbe wie public void m() { synchronized (this) { ... } }.
Es wird also auf this synchronisiert, so dass kein anderer Thread gleichzeitig auf this synchronisieren (i.e. "Den Monitor bekommen") kann.
Das kann natürlich über mehrere Codestellen bzw. Methoden sich erstrecken.
Ah ok, also liegt es daran dass dann die einzelnen Befhele wieder aus vielen Maschinenbefehlen bestehen und diese sich wieder untereinander verzahnen können?
 

frager2345

Aktives Mitglied
Ein Problem hier kann tatsächlich sein, dass die Ausgabe nicht wartet, bis die Threads fertig sind. Das wäre synchronized auch nicht zwingend ausreichend, denn es mag ja passieren, dass ein Thread angestartet wurde aber der Aufruf noch nicht gestartet wurde. Dann wäre das print vor dem inc oder dev aufgerufen worden.

Das Synchronized behebt aber ein anderes Problem:

Die Zeile value += 1 ist nicht atomar. Es wird also gemacht:
Der Wert value wird gelesen.
Dann wird diesem gelesenen Wert 1 hinzu addiert.
Das Ergebnis wird in value gelesen.

Beim anderen wäre es ähnlich - nur eben würde 10 abgezogen.

Was also nun bei zwei Threads passieren könnte:
Thread1: value wird gelesen (0)
Thread2: value wird gelesen (0)
Thread1: addiert 1 zur 0 (1)
Thread1: Schreibt die 1 zurück
Thread2 zieht 10 ab (0-10 = -10)
Thread2 schreibt die -10
==> Das Ergebnis -10 hat man nun.
Achse ok, ja dann würde join nicht reichen. Danke dir!
 

httpdigest

Top Contributor
Ah ok, also liegt es daran dass dann die einzelnen Befhele wieder aus vielen Maschinenbefehlen bestehen und diese sich wieder untereinander verzahnen können?
Innerhalb solch eines niedrigen Abstraktionslevels würde ich das jetzt nicht beschreiben, aber grundsätzlich: ja.
Selbst bei Maschinenbefehlen ist es nicht (immer) so, dass ein einzelner z.B. x86 Befehl/Opcode atomar ist, da er wiederum aus mehreren µ-Operations in der CPU zusammengesetzt sein kann, die wiederum separat/einzeln gescheduled werden und unterbrochen werden können. Beispiel bei x86 ist INC <reg/mem>. (ja, es sei denn, du nutzt den lock Prefix bei x86).
 

frager2345

Aktives Mitglied
Innerhalb solch eines niedrigen Abstraktionslevels würde ich das jetzt nicht beschreiben, aber grundsätzlich: ja.
Selbst bei Maschinenbefehlen ist es nicht (immer) so, dass ein einzelner z.B. x86 Befehl/Opcode atomar ist, da er wiederum aus mehreren µ-Operations in der CPU zusammengesetzt sein kann, die wiederum separat/einzeln gescheduled werden und unterbrochen werden können. Beispiel bei x86 ist INC <reg/mem>. (ja, es sei denn, du nutzt den lock Prefix bei x86).
Ok alles klar, danke für die Antworten!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Welche Methoden laufen im neuen thread ?? Java Basics - Anfänger-Themen 9
K Thread - Methoden in die run Methode Schreiben Java Basics - Anfänger-Themen 5
S Methoden Multi-Thread und Methoden Objects. Java Basics - Anfänger-Themen 1
O Zwei Methoden zueinander Thread-safe machen (Locken) Java Basics - Anfänger-Themen 9
E Methoden in neuem Thread erstellen Java Basics - Anfänger-Themen 6
R 2 methoden 1 Thread ? Java Basics - Anfänger-Themen 6
M mehrer run methoden in einem Thread Java Basics - Anfänger-Themen 7
A Andere Methoden aus einem Thread starten Java Basics - Anfänger-Themen 8
R Frage zu Thread und aufruf von Methoden Java Basics - Anfänger-Themen 2
B Methoden in einem Thread ausführen Java Basics - Anfänger-Themen 2
Leyla Thread isInterrupt Java Basics - Anfänger-Themen 18
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
F influxdb Upload in eigenem Thread Java Basics - Anfänger-Themen 2
berserkerdq2 Größter unterschied von extends thread und implements runnable? Java Basics - Anfänger-Themen 2
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
A Thread - Synchronized Java Basics - Anfänger-Themen 10
A Thread Producer - Consumer Java Basics - Anfänger-Themen 1
A Thread-Semhapore Java Basics - Anfänger-Themen 0
A Thread Exchanger Java Basics - Anfänger-Themen 22
A Thread-Cyclicbarrier Java Basics - Anfänger-Themen 4
B In einem Thread Endlosschleife beenden Java Basics - Anfänger-Themen 19
A Thread-Verklemmung Java Basics - Anfänger-Themen 10
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
A Thread find number Java Basics - Anfänger-Themen 8
F Thread.sleep() Java Basics - Anfänger-Themen 5
F Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at main.main(main.java:11) Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 3
M Exception in thread "main" java.util.NoSuchElementException Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 8
B Compiler-Fehler Fehlermeldung Exception in thread, falsche Eingabewert Java Basics - Anfänger-Themen 2
M Thread-Zustände Java Basics - Anfänger-Themen 6
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
S Kriege Fehler "Exception in thread" beim Benutzen von SubStrings. Java Basics - Anfänger-Themen 2
B Endlosschleife Thread sauber beenden Java Basics - Anfänger-Themen 19
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
C Thread und TimerTask, Verstädnisproblem Java Basics - Anfänger-Themen 10
amgadalghabra Sorting Thread Launcher Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
A Thread Java Basics - Anfänger-Themen 4
A Thread Java Basics - Anfänger-Themen 1
A Thread Java Basics - Anfänger-Themen 0
R Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 5
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 1
B Thread / Prozess stoppen? Java Basics - Anfänger-Themen 22
I Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 Java Basics - Anfänger-Themen 3
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
W Thread Aufgabe - Vorgehensweise Java Basics - Anfänger-Themen 8
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 0
J Threads PrograssBar update während thread Java Basics - Anfänger-Themen 13
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
R Exception in thread "main" java.lang.NullPointerException Java Basics - Anfänger-Themen 10
J JavaFX -> SocketIO -> Thread -> Update Label Java Basics - Anfänger-Themen 13
J Thread Handling Java Basics - Anfänger-Themen 9
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
C Thread in Methode + raus aus der Schleife Java Basics - Anfänger-Themen 10
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
F Daten von Thread an den aufrufenden zurückgeben Java Basics - Anfänger-Themen 22
C Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 Java Basics - Anfänger-Themen 3
B Thread Problem Java Basics - Anfänger-Themen 7
N KeyListener in Thread Java Basics - Anfänger-Themen 0
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
W JLabel in Main aus Thread verändern. Java Basics - Anfänger-Themen 4
D Ausgeben welcher Thread gerade Arbeitet Java Basics - Anfänger-Themen 8
N Threads Thread-Fehler Java Basics - Anfänger-Themen 2
F Thread um Uhrzeit ausführen Java Basics - Anfänger-Themen 5
F Get/Post als eigener Thread mit Rückgabe Java Basics - Anfänger-Themen 5
J Exception in thread "main" Java Basics - Anfänger-Themen 1
F Thread der auf eine Queue wartet, sicher beenden Java Basics - Anfänger-Themen 4
B Animation mit Thread(s) Java Basics - Anfänger-Themen 23
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
M Threads Jede Klasse einem Thread zuweisen Java Basics - Anfänger-Themen 7
J Java Thread cancel() und wiederbeleben Java Basics - Anfänger-Themen 4
J BouncingBalls 1 Thread Java Basics - Anfänger-Themen 3
L Fehler: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 4
J Timer oder Thread programmieren ? Java Basics - Anfänger-Themen 10
fLooojava Laufender Thread | Boolean ändern Java Basics - Anfänger-Themen 9
T Thread Pool mit Work Stealing Java Basics - Anfänger-Themen 1
R Java Thread Java Basics - Anfänger-Themen 10
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
N Threads Exception in thread "main"... Feher bei dem Versuch ein Radius zu berechnen Java Basics - Anfänger-Themen 4
A Code läuft nicht, Fehlermeldung Exception in thread "main" java.lang.Error: Unresolved compilation " Java Basics - Anfänger-Themen 11
V Threads Exception in Thread behandeln Java Basics - Anfänger-Themen 3
J Thread erstellen (BlueJ Projekt) Java Basics - Anfänger-Themen 3
P Exception in thread "main" java.lang.NoClassDefFoundError: Java Basics - Anfänger-Themen 1
F Threads Variable aus einem Thread in main Methode? Java Basics - Anfänger-Themen 9
K Exception in thread "main" Java Basics - Anfänger-Themen 7
L Thread-Frage Java Basics - Anfänger-Themen 2
E Was ist ein idle-thread? Java Basics - Anfänger-Themen 1
D Exception in thread "AWT-EventQueue-0" Java Basics - Anfänger-Themen 8
J Threads Prozess in Thread auslagern Java Basics - Anfänger-Themen 2
G Thread mehrmals starten und schliessen Java Basics - Anfänger-Themen 6
F Thread Koordination (Vorteile/Nachteile) Java Basics - Anfänger-Themen 0
O Thread aus dem Thread stoppen Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben