Synchronisation in Java: Was, wie und warum?



In diesem Artikel zur Synchronisierung in Java erfahren Sie, wie Sie die Multithread-Programme synchronisieren.

Multithread-Programme können regelmäßig auf einen Umstand stoßen, bei dem mehrere Versuchen Sie, auf dieselbe Ressource zuzugreifen, die zu betrügerischen und verblüffenden Ergebnissen führt. Dies kann mithilfe der Synchronisierung in Java gelöst werden. Nur ein einzelner bestimmter Thread kann zu einem bestimmten Zeitpunkt auf die Ressource zugreifen. Dieser Artikel hilft Ihnen, sich mit der Synchronisationsstrategie vertraut zu machen.

Ich werde die Themen in dieser Reihenfolge diskutieren:





Lass uns anfangen!

Warum Synchronisation in Java verwenden?



Wenn Sie mit mindestens zwei Threads in einem Programm beginnen, besteht möglicherweise die Möglichkeit, dass mehrere Threads versuchen, auf dieselbe Ressource zuzugreifen. Aufgrund von Parallelitätsproblemen kann es sogar zu einem unerwarteten Ergebnis kommen.

Syntax ::

synchronisiert (Objektkennung) {// Zugriff auf gemeinsam genutzte Variablen und andere gemeinsam genutzte Ressourcen}

Beispielsweise, Versuchen Sie, in eine entsprechende Datei zu schreiben. Dies kann die Daten beschädigen, da einer der Threads die Daten überschreiben kann oder wenn ein Thread die Daten öffnetDieselbe Datei zur gleichen Zeit, ein anderer Thread schließt möglicherweise dieselbe Datei.Es ist erforderlich, die Aktion mehrerer Threads zu synchronisieren. Dies kann mit einem Konzept namens implementiert werden M. onitors .



  • Jeder ist einem Monitor zugeordnet, den ein Thread sperren oder entsperren kann.
  • Es kann jeweils nur ein Thread eine Sperre für einen Monitor halten.
  • Java Die Programmiersprache bietet eine sehr praktische Möglichkeit, Threads zu erstellen und ihre Aufgabe mithilfe der zu synchronisieren Synchronisiert Blöcke.
  • Außerdem werden die gemeinsam genutzten Ressourcen in diesem bestimmten Block gespeichert.

Synchronisierte Blöcke in Java sind mit dem gekennzeichnet Synchronisiert Stichwort. Dieser Block in Java ist für ein Objekt synchronisiert.In allen Blöcken, die mit demselben Objekt synchronisiert sind, kann jeweils nur ein Thread ausgeführt werden. Alle anderen Threads, die versuchen, in den synchronisierten Block einzutreten, werden blockiert, bis der Thread innerhalb des synchronisierten Blocks den Block verlässt.

Arten der Synchronisation

Grundsätzlich stehen zwei Arten der Synchronisation zur Verfügung. Sie sind:

  1. Prozesssynchronisation: Die gleichzeitige Ausführung mehrerer Threads oder Prozesse, um einen Zustand zu erreichen, in dem sie sich auf eine bestimmte Abfolge von Aktionen festlegen.
  2. Thread-Synchronisation: Zu Zeiten, wenn mehr als ein ThreadWenn Sie versuchen, auf eine freigegebene Ressource zuzugreifen, müssen Sie sicherstellen, dass die Ressource nur von einem Thread bei verwendet wirdeine Zeit.

Lassen Sie uns nicht auf die Details dieser Typen eingehen und versuchen zu verstehen, was Sperren sind .

Sperrt in Java

Wie bereits erwähnt, basiert die Synchronisierung auf einer internen Entität, die als sperren oder Monitor . Jedem Objekt ist eine Sperre zugeordnet. Ein Thread, der konsistenten Zugriff auf die Felder eines Objekts benötigt, muss daher vor dem Zugriff die Sperre des Objekts abrufen und die Sperre dann aufheben, wenn die Arbeit erledigt ist.

Ab Java 5 enthält das Paket java.util.concurrent.locks viele Sperrimplementierungen.

So sieht ein Schloss aus:

öffentliche Klasse Lock {private boolean isLocked = false public synchronized void lock () löst InterruptedException aus {while (isLocked) {wait ()} isLocked = true} public synchronized void void () {isLocked = false notify ()}}

Die lock () -Methode sperrt die Lock-Instanz, sodass alle Threads, die lock () aufrufen, blockiert werden, bis execute () ausgeführt wird.

Multithreading ohne Synchronisation

Hier ist ein einfaches Beispiel, das den Zählerwert in einer Sequenz druckt und jedes Mal, wenn wir ihn ausführen, ein anderes Ergebnis basierend auf der CPU-Verfügbarkeit für einen Thread erzeugt. Schau dir das an!

Klasse Multithread {public void printCount () {try {for (int i = 5 i<0 i--) { System.out.println('Counter --- ' + i ) } } catch (Exception e) { System.out.println('Thread interrupted.') } } } class Thread extends Multithread { private Thread t private String threadName Multithread MT Thread( String name, Multithread mt) { threadName = name MT= mt } public void run() { MT.printCount() System.out.println('Thread ' + threadName + ' exiting.') } public void start () { System.out.println('Starting ' + threadName ) if (t == null) { t = new Thread (this, threadName) t.start () } } } public class TestThread { public static void main(String args[]) { Multithread MT = new Multithread() Thread t = new Thread( 'Thread - 1 ', MT) Thread t1 = new Thread( 'Thread - 2 ', MT) t.start() t1.start() // wait for threads to end try { t.join() t1.join() } catch ( Exception e) { System.out.println('Interrupted') } } }

Die Ergebnisse des obigen Programms ergeben Folgendes:

Ausgabesynchronisation in Java-Edureka

Multithreading mit Synchronisation

Dies ist das gleiche Beispiel wie oben, es wird jedoch der Zählerwert in der Sequenz gedruckt. Jedes Mal, wenn wir es ausführen, wird das gleiche Ergebnis erzielt.

Klasse Multithread {public void printCount () {try {for (int i = 5 i> 0 i--) {System.out.println ('Zähler ---' + i)}} catch (Ausnahme e) {System. out.println ('Thread unterbrochen.')}}} Klasse Thread erweitert Multithread {privater Thread t privater String threadName Multithread MT Thread (Stringname, Multithread mt) {threadName = Name MT = mt} public void run () {synchronized ( MT) {MT.printCount ()} System.out.println ('Thread' + Threadname + 'Beenden')} public void start () {System.out.println ('Starten' + Threadname) if (t == null) {t = neuer Thread (this, threadName) t.start ()}}} öffentliche Klasse TestThread {public static void main (String args []) {Multithread MT = neuer Multithread () Thread T = neuer Thread ('Thread - 1 ', MT) Thread T1 = neuer Thread (' Thread - 2 ', MT) T.start () T1.start () // Warten Sie, bis die Threads beendet sind. Versuchen Sie {T.join () T1.join ()} catch (Ausnahme e) {System.out.println ('Interrupted')}}}

Die Ausgabe ist unten dargestellt:

Synchronisiertes Schlüsselwort

synchronisiertes Schlüsselwort markiert einen Block oder eine Methode als kritischen Abschnitt. In einem kritischen Abschnitt wird jeweils nur ein Thread ausgeführt, und der Thread enthält die Sperre für den synchronisierten Abschnitt. Dies synchronisiert Schlüsselwort hilft beim Schreiben gleichzeitig Teile jeder Anwendung. Es schützt auch gemeinsam genutzte Ressourcen innerhalb des Blocks.

Das synchronisierte Schlüsselwort kann verwendet werden mit:

Lassen Sie uns den Codeblock diskutieren.

Synchronisiertes Schlüsselwort: Ein Codeblock

Syntax

Die allgemeine Syntax zum Schreiben eines synchronisierten Blocks lautet:

synchronized (lockObject) {// synchronisierte Anweisungen}

Wenn ein Thread die synchronisierten Anweisungen innerhalb des Blocks ausführen möchte, muss er die Sperre auf dem Monitor von lockObject erhalten. Es kann jeweils nur ein Thread den Monitor eines Sperrobjekts erfassen. Alle anderen Threads müssen also warten, bis der aktuell ausgeführte Thread die Sperre erhält, und seine Ausführung beenden.
Auf diese Weise wird die synchronisiert Das Schlüsselwort garantiert, dass jeweils nur ein Thread die synchronisierten Blockanweisungen ausführt, und verhindert so, dass mehrere Threads die im Block vorhandenen gemeinsam genutzten Daten beschädigen.

Wert übergeben und Referenz Java übergeben

Hinweis ::

  • Wenn ein Thread in den Ruhezustand versetzt wird (mit Schlaf() Methode) dann wird die Sperre nicht aufgehoben. Während dieser Ruhezeit führt kein Thread die synchronisierten Blockanweisungen aus.
  • Java-Synchronisation wird werfen NullPointerException wenn das in ‘ synchronisiert (Sperre) ' ist Null.

Lassen Sie uns nun die Methode diskutieren.

Synchronisiertes Schlüsselwort: Eine Methode

Syntax

Die allgemeine Syntax zum Schreiben von a synchronisierte Methode ist:

synchronisierte Methode (Parameter) {// synchronisierter Code}

Hier lockObject ist nur eine Referenz auf ein Objekt, dessen Sperre dem Monitor zugeordnet ist, der die synchronisierten Anweisungen darstellt.

Ähnlich wie beim synchronisierten Block muss ein Thread die Sperre für das verbundene Monitorobjekt mit der synchronisierten Methode erlangen. Bei einer synchronisierten Methode lautet das Sperrobjekt:

  • Objekt '.class' - wenn die angegebene Methode ist statisch .
  • 'Dieses' Objekt - wenn die Methode ist nicht statisch . 'Dies' ist die Referenz auf das aktuelle Objekt, in dem die synchronisierte Methode aufgerufen wird.

Java synchronisiertes Schlüsselwort ist Wiedereinsteiger in der Natur. Wenn eine synchronisierte Methode eine andere synchronisierte Methode aufruft, für die dieselbe Sperre erforderlich ist, kann der aktuelle Thread, der die Sperre hält, in diese Methode eintreten, ohne die Sperre zu erwerben.

Lassen Sie uns zum letzten Thema dieses Artikels übergehen und auf die Hauptunterschiede zwischen dem synchronisierten Schlüsselwort und dem Synchronisationsblock hinweisen.

Unterschied zwischen synchronisiertem Schlüsselwort und synchronisiertem Block

  • Wenn Sie ein synchronisiertes Schlüsselwort mit einem verwenden Methode erhält es eine Sperre im Objekt für die gesamte Methode. Dies bedeutet, dass kein anderer Thread eine synchronisierte Methode verwenden kann, bis der aktuell aufgerufene Thread seine Ausführung beendet hat.
  • Synchronisiert Block Erlangt eine Sperre im Objekt nur zwischen Klammern, nachdem das synchronisierte Schlüsselwort angegeben wurde. Dies bedeutet, dass kein anderer Thread eine Sperre für das bereits gesperrte Objekt erhalten kann, bis der Block beendet wird. Andere Threads können jedoch auf den Rest des in der Methode vorhandenen Codes zugreifen.

Dies bringt uns zum Ende dieses Artikels, in dem wir erläutert haben, wie genau die Synchronisierung in Java funktioniert. Ich hoffe, Sie sind mit allem klar, was Ihnen in diesem Tutorial mitgeteilt wurde.

Besuche die von Edureka, einem vertrauenswürdigen Online-Lernunternehmen mit einem Netzwerk von mehr als 250.000 zufriedenen Lernenden auf der ganzen Welt. Wir sind hier, um Ihnen bei jedem Schritt auf Ihrer Reise zu helfen. Neben diesen Fragen zu Java-Interviews erstellen wir einen Lehrplan, der für Studenten und Fachleute konzipiert ist, die Java-Entwickler werden möchten.

Hast du eine Frage an uns? Bitte erwähnen Sie dies im Kommentarbereich dieser „Synchronisation in Java '' Artikel und wir werden uns so schnell wie möglich bei Ihnen melden.