anscheint habe ich die ganze Sache noch nicht so recht verstanden.
Ich möchte 3 Threads erstellen, die eine gemeinsame Zählvariable besitzen, die synchronisiert werden soll.
Dafür ist synchronized nicht. Wenn du verschiedene Instanzen eines Objekts separat behandelst, gibt es nichts zu synchronisieren. Synchronisiert werden muss dann, wenn mehrere Threads auf das selbe Objekt zugreifen.
Du könntest einen statischen Counter benutzen oder ein einziges Counter-Objekt initialisieren und allen drei Threads (z. B. über den Konstruktor) zuweisen.
Dafür ist synchronized nicht. Wenn du verschiedene Instanzen eines Objekts separat behandelst, gibt es nichts zu synchronisieren. Synchronisiert werden muss dann, wenn mehrere Threads auf das selbe Objekt zugreifen.
Du könntest einen statischen Counter benutzen oder ein einziges Counter-Objekt initialisieren und allen drei Threads (z. B. über den Konstruktor) zuweisen.
Nun greifen sie wohl allerdings zeitgleich auf den Counter zu ... und so soll es ja nicht sein .... jede Ausgabe des Counters-Standes soll ja nur genau einmal erfolgen.
Ein synchronized in der Methodendeklaration bewirkt das gleiche, als würde man den gesamten Rumpf dieser Methode von einem synchronized(this) umschließen. Bei this handelt es sich allerdings für jedes Objekt um ein anderes, weshalb ein synchronized(this) praktisch wirkungslos ist.
Nimm das synchronized doch mal aus den Methodendeklarationen raus und packe dafür die Rümpfe jeweils in einen synchronized(Counter.class)-Block:
Code:
public int getCounterValue() {
synchronized(Counter.class){
return Counter;
}
}
Sollte so gehen wie Ark schreibt. Eine Alternative wäre java.util.concurrent.atomic.AtomicReference, das ist sozusagen ein synchronisierter Wrapper um die Variable.
funktioniert auch nicht. Habs ausprobiert. Es sieht zuerst so aus, als ob
der Counter synchronisiert hochgezählt wird, aber wenn die Threads immer genauso lang
schlafen, dann kommt bei mir
Nein. Im zweiten Beispiel gibt es doch nur noch eine Counter-Variable. Dann ist es völlig egal, ob hier auf die Variable oder die Klasse synchronisiert wird. Da kommt das selbe raus.
Wenn wirklich das ausgegeben werden soll, was oben gefordert wird, muss das Inkrementieren und Holen des Wertes eine atomare Transaktion sein, z.B.