Wenn Sie das synchronisierte Schlüsselwort verwenden, wird ein Mutex verwendet, um Thread-Sicherheit und synchronen Zugriff auf gemeinsam genutzte Ressourcen sicherzustellen. Um komplexe gleichzeitige Aufgaben auszuführen, ist häufig eine weitere koordinierte Ausführung zwischen Threads erforderlich. Beispielsweise ist der Warte-/Benachrichtigungsmodus ein koordinierter Ausführungsmechanismus in einer Multithread-Umgebung.
Das Erlangen und Freigeben von Sperren über die API (mithilfe eines Mutex) oder das Aufrufen von Wait/Notify und anderen Methoden sind Aufrufmethoden auf niedriger Ebene. Darüber hinaus ist es notwendig, Abstraktionen auf höherer Ebene für die Thread-Synchronisierung zu erstellen. Die häufig verwendete Synchronisationshilfsklasse dient dazu, den Synchronisationsaktivitätsmechanismus zwischen zwei oder mehr Threads weiter zu kapseln. Ihr internes Prinzip besteht darin, mithilfe der vorhandenen zugrunde liegenden API eine komplexe Koordination zwischen Threads zu erreichen.
Es gibt 5 Synchronisierungshilfsklassen, die für gängige Synchronisierungsszenarien geeignet sind:
1. Semaphore Semaphore ist ein klassisches Synchronisationstool. Semaphoren werden häufig verwendet, um die Anzahl der Ressourcen (physisch oder logisch) zu begrenzen, auf die ein Thread gleichzeitig zugreifen kann.
2.CountDownLatch ist eine sehr einfache, aber häufig verwendete Synchronisationshilfsklasse. Sein Zweck besteht darin, einem oder mehreren Threads das Blockieren zu ermöglichen, bis eine Reihe von Vorgängen, die in anderen Threads ausgeführt werden, abgeschlossen ist.
3. CyclicBarrier ist ein zurücksetzbarer Mehrweg-Synchronisationspunkt, der in bestimmten gleichzeitigen Programmierszenarien nützlich ist. Dadurch kann eine Gruppe von Threads aufeinander warten, bis ein gemeinsamer Barrierepunkt erreicht ist. CyclicBarrier ist in Programmen nützlich, die eine Reihe von Threads fester Größe umfassen, die von Zeit zu Zeit aufeinander warten müssen. Da die Barriere nach der Freigabe des wartenden Threads wiederverwendet werden kann, wird sie als zyklische Barriere bezeichnet.
4. Phaser ist eine wiederverwendbare Synchronisationsbarriere, die in ihrer Funktion CyclicBarrier und CountDownLatch ähnelt, jedoch flexibler in der Verwendung ist. Es eignet sich sehr gut für die synchrone Koordinierung von Phased-Computing-Aufgaben in einer Multithread-Umgebung (wenn eine Synchronisierung zwischen Unteraufgaben im Fork/Join-Framework erforderlich ist, wird Phaser bevorzugt).
5.Exchanger ermöglicht es zwei Threads, Objekte an einem bestimmten Treffpunkt auszutauschen, was bei bestimmten Pipeline-Designs nützlicher ist. Exchanger stellt einen Synchronisationspunkt bereit, an dem zwei Threads Daten austauschen können. Jeder Thread stellt seinem Partner-Thread über den Eintrag der Methode „exchange()“ Daten zur Verfügung, empfängt die von seinem Partner-Thread bereitgestellten Daten und gibt sie zurück. Wenn zwei Threads Objekte über Exchanger austauschen, ist der Austausch für beide Threads sicher. Exchanger kann als bidirektionale Form von SynchronousQueue betrachtet werden, die bei Anwendungen mit genetischen Algorithmen und Pipeline-Design nützlicher ist.