Die Leute erzählen von zwei Arten von Multi-Thread-Sperren - Objekt und Klasse.
Eine Klasse ist ein Objekt. Es gibt nur eine Art von Sperrung in der Java -Sprache : Jedes Objekt (einschließlich jeder Klasse) hat einen Mutex, der durch einen synchronized
-Block oder eine synchronized
-Methode gesperrt werden kann. Das Objekt, das gesperrt werden soll, ist implizit in einer synchronized
-Methode: Es ist die "This" -Instanz für eine Instanzmethode und es ist das Klassenobjekt für eine statische Methode.
Einer der häufigsten Anfängerfehler besteht darin, dass zwei verschiedene Threads nicht gleichzeitig in den gleichen synchronized
-Block gelangen können. Sie können , und es gibt viele Fragen und Antworten hier in StackOverflow, die es beweisen. Ein weiterer Fehler besteht darin zu glauben, dass wenn ein Thread auf ein Objekt synchronisiert wird, andere Threads das Objekt nicht ändern können. Sie können und sie tun es.
Die Synchronisierung verhindert, dass zwei oder mehr Threads gleichzeitig auf dem selben Objekt synchronisiert werden. Welches Objekt ist das richtige Objekt? Es geht darum, Ihre Daten zu schützen. Wenn die Struktur, die Sie schützen möchten, beispielsweise eine verknüpfte Liste ist, dann wäre eine gute Wahl für jede Methode, die auf die Liste zugreift, um sie auf dem Listenkopf zu synchronisieren. Wenn Sie globale Daten schützen möchten (z. B. static
-Variablen), möchten Sie ein globales Objekt (z. B. das Klassenobjekt, das die Variablen besitzt) synchronisieren. Wichtig ist, dass Sie Daten lesen / schreiben (aka, "veränderbare Daten"), auf die mehr als ein Thread zugreift, dann muss jede Methode, die auf dieselben Daten zugreift, auf die selbe Sperre synchronisiert werden.
Es gibt eine andere Art von Sperren in Java, aber nicht in der Java Sprache ; Es ist in der Java-Standardbibliothek. Es ist über Objekte verfügbar, die die Schnittstelle java.util.concurrent.locks.Lock implementieren. Natürlich implementiert ein Lock-Objekt (wie jedes Objekt) auch die erste Art der Sperrung, aber Sie sollten niemals je auf einem Lock-Objekt synchronisieren, es sei denn, Sie möchten den Leuten den Eindruck vermitteln, dass Sie ahnungslos sind Neuling.
Die Sperrung java.util.concurrent-style ist mächtiger als die Verwendung von synchronized
blocks wegen ihrer expliziten Methoden lock () und unlock (). Zum Beispiel ist es möglich, dass eine Methode eine Sperre sperrt und eine andere Methode, um sie zu entsperren. Das kann zu Code führen, der schwierig zu verstehen ist, und ich würde es nicht tun, wenn ich nicht einen sehr guten Grund hätte, aber manchmal gibt es gute Gründe.