ich zur Zeit über Intrinsic Locks and Synchronization auf oracle.com lese, wo ich zu diesem besonderen Beispiel kam:Intrinsic Schlösser und Synchronisation
Synchronisierte Aussagen sind auch nützlich für die Gleichzeitigkeit mit feinkörnigem Synchronisation zu verbessern. Angenommen, die Klasse MsLunch hat beispielsweise zwei Instanzfelder,
c1
undc2
, die niemals zusammen verwendet werden. Alle Updates dieser Felder müssen synchronisiert werden, aber es gibt keinen Grund zu verhindern, dass eine Aktualisierung vonc1
mit einer Aktualisierung vonc2
verschachtelt wird - und dies reduziert die Nebenläufigkeit, indem eine unnötige Blockierung erzeugt wird. Anstatt synchronisierte Methoden zu verwenden oder die damit verbundene Sperre anderweitig zu verwenden, erstellen wir zwei Objekte, um nur Sperren bereitzustellen.
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
Vor diesem Abschnitt synchronized
Verfahren, in denen erklärt:
public synchronized void increment() {
this.c++;
}
Welche sein sollte, und mir bitte korrigieren, wenn ich falsch bin, das gleiche wie
public void increment() {
synchronized(this) {
c++;
}
}
wenn Ich füge keine Funktionalität zu increment()
hinzu, ist das richtig?
Meine Frage ist jetzt aus dem Satz kommt:
aber es gibt keinen Grund, ein Update von
c1
zu verhindern, dass verschachtelte mit einem Update vonc2
sein Ich bin nicht sicher, ob ich vollständig verstehen, was "interleaved" bedeutet in diesem Zusammenhang. Bedeutet es, dass wenn ich z.B. entfernen lock2
aus dem MsLunch
Beispiel:
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
// private Object lock2 = new Object(); // 'lock2' is no more!
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock1) { // Using 'lock1' here too
c2++;
}
}
}
ich in Schwierigkeiten mit Sperren bekommen? Sagen thread-1
läuft in , erhält die Sperre von lock1
, aber wird ausgesetzt, bevor in der Lage sein, die Sperre zu erhöhen oder zu lösen. Jetzt thread-2
wird inc2()
eingeben, wo eine andere Sperre für lock1
erstellt wird. Wird das vermieden, indem ein anderer lock2
verwendet wird und ist das der Grund, warum ich nicht einfach this
als Lock-Provider verwenden würde? Oder mit anderen Worten: Kann das ein Problem verursachen?
Nein, Sie können nicht in * Schwierigkeiten * geraten, Sie werden nur unnötigerweise verhindern, dass 'c1' und' c2' gleichzeitig erhöht werden, da sie die gleiche Sperre teilen (egal ob 'this' oder a Trennen Sie 'lock1') und haben Sie daher eine Abhängigkeit zwischen ihnen durch die Sperre. – Kayaman
@Kayaman Oh, die deutsche Übersetzung von "interleaved" ist so etwas wie "ineinander" oder "ineinander", also bin ich ein bisschen verwirrt. Aber warum verhindert das gleichzeitig "c1" und "c2"? Wenn 'lock1' im Beispiel' lock1' nur eine Sperre "* anywhere *" im Code enthält, bedeutet das, dass es auch anderswo blockiert wird? So muss 'thread-2' warten, bis' thread-1' '' c1' 'aktualisiert, bevor '2' aktualisiert werden kann. Das bedeutet auch, dass jedes Objekt nur eine einzige Sperre zur gleichen Zeit bereitstellen kann - das war mir beim Lesen des Kapitels nicht klar. – displayname
Ja, jedes Objekt bietet eine Sperre nach der anderen. Das ist die ganze Idee, warum synchronisiert so funktioniert. – Kayaman