Zunächst einmal vergessen synchronisiert Methoden. Eine so genannte synchronisierte Methode ...
synchronized AnyType foobar(...) {
doSomething();
}
ist nichts anderes als eine Verknüpfung Weg, dies zu schreiben:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
Es ist nichts Besonderes über die Methode in jedem Fall. Was besonders ist, ist der synchronisierte Block, und was ein synchronisierter Block macht, ist sehr einfach. Wenn die JVM führt diese:
synchronized(foo) {
doSomething();
}
Es wertet zunächst die Expression foo
. Das Ergebnis muss eine Objektreferenz sein. Dann sperrt es das Objekt, führt den Rumpf des Blocks synchronized
aus und entsperrt das Objekt.
Aber was bedeutet gesperrt bedeuten? Es kann bedeuten, weniger als Sie denken. Es tut nicht verhindern, dass andere Threads das Objekt verwenden.Es hindert sie nicht daran, auf die Felder des Objekts zuzugreifen oder die Felder zu aktualisieren. Das Sperren eines Objekts verhindert nur, dass andere Threads dasselbe Objekt nicht gleichzeitig sperren können.
Wenn Thread A versucht, synchronized(foo) {...}
einzugeben, während Thread B bereits foo gesperrt ist (entweder im selben synchronized
Block oder in einem anderen), wird Thread A gezwungen zu warten, bis Thread B die Sperre aufhebt.
Sie verwenden synchronized
Blöcke Daten zu schützen.
Angenommen, Ihr Programm verfügt über eine Sammlung von Objekten, die sich in verschiedenen -Status befinden können. Nehmen wir an, dass einige Zustände sinnvoll sind, aber es gibt andere Zustände, die keinen Sinn ergeben. ungültig Staaten.
Angenommen, es ist nicht möglich, dass ein Thread die Daten von einem gültigen Status in einen anderen gültigen Status ändert, ohne dass vorübergehend einen ungültigen Status erstellt.
Wenn Sie den Code setzen, der den Zustand in einem synchronized(foo)
Block ändert, und Sie setzen jeden Codeblock, der der Zustand in einen synchronisierten Block sehen, der die gleiche Objekt sperrt, foo
Sie dann verhindert, dass andere Threads den temporären ungültigen Status sehen.
Ihre Erklärung ist sehr nett und leicht zu verstehen. Da Sie mehr ins Detail gegangen sind, muss ich fragen ... wo werden andere Threads für das Entsperren gesperrt (warten), wenn ein Thread das Objekt sperrt? Ich kenne seine wahrscheinlich "Debugging" -Frage, aber als ich alle Threads während meines Deadlocks suspendierte, war ich verwirrt, weil ich zwei Threads fand, die beide die gleiche synchronisierte Methode ausführten - ich würde einen am Anfang erwarten und einen zu Beginn eines anderen synchronisieren Methode (um eine Schleife zu erstellen). – arenaq
@arenaq _Wohin?_ wie würde ein Debugger Ihnen zeigen? Ich weiß es nicht. Ich habe in Debuggern nicht viel Java-Code angeschaut. Ich bin eher ein C-Programmierer. Die Synchronisation ist keine intrinsische Sprachfunktion in C, daher zeigt der Debugger in C den Thread, der in einem Synchronisationssystemaufruf gestoppt wurde, von innerhalb eines Aufrufs zu einer Synchronisationsbibliotheksfunktion von irgendwo in meinem Code. Die Java-Debugger, die ich verwendet habe, zeigen keine Systemaufrufe oder die inneren Abläufe der JVM, und ich erinnere mich nicht, jemals den Stapel eines Java-Threads, der auf eine Sperre wartete, zu untersuchen. –
Vergiss es, sein nicht verwandtes Q sowieso ... sollte ein neues Thema sein. – arenaq