mittelding
2012-03-24, 22:44:10
Hallo!
Ich tu mich zugegebenermaßen etwas schwer mit dem synchronized Keyword in Java zur Threadsynchronisierung. Mir ist schon klar warum man Synchronisierung braucht, aber die Auswirkungen von synchronized kann ich noch nicht ganz überschauen. Aber mal von vorne.
Da man ja Methoden und Blöcke mit synchronized markieren kann, soll es zunächst um die Variante für Methoden gehen.
Wenn man also eine Methode auf synchronized setzt, dann kann sie nur von einem Thread am Stück ausgeführt werden, ohne dass ein anderer Thread sie zwischenzeitlich nochmal ausführen kann. Schön und gut.
Aber:
Die (objektspezifischen) Variablen/Objekte, die man innerhalb dieser Methode manipuliert, die sind in dieser Zeit trotzdem nicht vor Änderungen von außen geschützt, richtig? Wenn ich also noch eine zweite (non-synchronized) Methode habe, die könnte zwischenzeitlich trotzdem reinpfuschen und meine angestrebte Konsistenz kaputt machen?
Bsp:
public void synchronized example (int number) {
this.a = number;
this.b = number;
Print("an exakt dieser Stelle sollten a und b identisch sein, vielleicht aber auch nicht");
}
Hier hätte ich zwar die Sicherheit, dass diese Methode nicht von mehreren Threads gleichzeitig ausgeführt wird und sich deswegen a und b am Ende unterscheiden. Aber ich hätte nicht die Sicherheit, dass a während dem setzen von b nicht bereits wieder von einem anderen Thread in einer anderen (nicht-synchronisierten) Methode geändert wurde, also wären a und b am ende evt. trotzdem unterschiedlich. Liege ich da richtig?
----
Zweite Frage, etwas kürzer: angenommen, eine Klasse hat 10 synchronized Methoden. Wird eine davon von Thread X ausgeführt, so kann eben diese von Thread Y nicht gleichzeitig ausgeführt werden. Könnte aber eine der anderen 9 Methoden in dieser Zeit ausgeführt werden von Thread Y? Oder anders: sobald eine synchronized-Methode läuft, ist dann nur diese für andere Threads gesperrt oder gleich auch alle anderen synchronized-Methoden, wobwohl diese garnicht betroffen sind?
Ich vermute stark letzteres, wollte nur nochmal sicher gehen.
---
Jetzt noch zu der Variante, bei welcher Blöcke mit synchronized markiert werden. Hier kann man ja hinter dem Keyword in runden Klammern ein Objekt angeben, dessen Monitor benutzt werden soll. Da dies bei Methoden nicht geht, sind synchronized Methoden implizit äquivalent zu
synchronized(this) { // Hier erst der Methodencode }
Ich stelle mir das so vor, dass nun der Monitor des Objekts überwacht, dass die Methode nur einmal ausgeführt wird. Was aber, wenn man dort nicht this angibt, sondern eine Objektvariable?
synchronized(this.a) { // do sth. mit a }
Was ist hier der Sinn?
Vielen Dank
Ich tu mich zugegebenermaßen etwas schwer mit dem synchronized Keyword in Java zur Threadsynchronisierung. Mir ist schon klar warum man Synchronisierung braucht, aber die Auswirkungen von synchronized kann ich noch nicht ganz überschauen. Aber mal von vorne.
Da man ja Methoden und Blöcke mit synchronized markieren kann, soll es zunächst um die Variante für Methoden gehen.
Wenn man also eine Methode auf synchronized setzt, dann kann sie nur von einem Thread am Stück ausgeführt werden, ohne dass ein anderer Thread sie zwischenzeitlich nochmal ausführen kann. Schön und gut.
Aber:
Die (objektspezifischen) Variablen/Objekte, die man innerhalb dieser Methode manipuliert, die sind in dieser Zeit trotzdem nicht vor Änderungen von außen geschützt, richtig? Wenn ich also noch eine zweite (non-synchronized) Methode habe, die könnte zwischenzeitlich trotzdem reinpfuschen und meine angestrebte Konsistenz kaputt machen?
Bsp:
public void synchronized example (int number) {
this.a = number;
this.b = number;
Print("an exakt dieser Stelle sollten a und b identisch sein, vielleicht aber auch nicht");
}
Hier hätte ich zwar die Sicherheit, dass diese Methode nicht von mehreren Threads gleichzeitig ausgeführt wird und sich deswegen a und b am Ende unterscheiden. Aber ich hätte nicht die Sicherheit, dass a während dem setzen von b nicht bereits wieder von einem anderen Thread in einer anderen (nicht-synchronisierten) Methode geändert wurde, also wären a und b am ende evt. trotzdem unterschiedlich. Liege ich da richtig?
----
Zweite Frage, etwas kürzer: angenommen, eine Klasse hat 10 synchronized Methoden. Wird eine davon von Thread X ausgeführt, so kann eben diese von Thread Y nicht gleichzeitig ausgeführt werden. Könnte aber eine der anderen 9 Methoden in dieser Zeit ausgeführt werden von Thread Y? Oder anders: sobald eine synchronized-Methode läuft, ist dann nur diese für andere Threads gesperrt oder gleich auch alle anderen synchronized-Methoden, wobwohl diese garnicht betroffen sind?
Ich vermute stark letzteres, wollte nur nochmal sicher gehen.
---
Jetzt noch zu der Variante, bei welcher Blöcke mit synchronized markiert werden. Hier kann man ja hinter dem Keyword in runden Klammern ein Objekt angeben, dessen Monitor benutzt werden soll. Da dies bei Methoden nicht geht, sind synchronized Methoden implizit äquivalent zu
synchronized(this) { // Hier erst der Methodencode }
Ich stelle mir das so vor, dass nun der Monitor des Objekts überwacht, dass die Methode nur einmal ausgeführt wird. Was aber, wenn man dort nicht this angibt, sondern eine Objektvariable?
synchronized(this.a) { // do sth. mit a }
Was ist hier der Sinn?
Vielen Dank