In Java verwenden wir Semaphore in der Thread-Synchronisation. Es wird verwendet, um den Zugriff auf eine gemeinsame Ressource zu steuern, die eine Zählervariable verwendet. Java bietet auch eine Semaphore-Klasse, die Konstruktoren und verschiedene Methoden enthält, um den Zugriff auf die gemeinsame Ressource zu kontrollieren. Wir werden sie später in diesem Abschnitt besprechen.

Bevor wir in diesem Abschnitt fortfahren, werden wir zunächst verstehen, was Semaphore ist, welche Arten von Semaphore es gibt, wie es funktioniert und wie man Semaphore implementiert. Nachdem wir alles darüber wissen, werden wir zu den Java Semaphor-Programmen übergehen.

Was ist ein Semaphor?

Ein Semaphor wird verwendet, um die Anzahl der Threads zu begrenzen, die auf eine gemeinsame Ressource zugreifen wollen. Mit anderen Worten, es handelt sich um eine nicht-negative Variable, die von den Threads gemeinsam genutzt wird und als Zähler bezeichnet wird. Sie legt das Limit für die Threads fest. Ein Mechanismus, bei dem ein Thread auf eine Semaphore wartet, kann von anderen Threads signalisiert werden.

  • Wenn der Zähler > 0 ist, wird der Zugriff auf gemeinsame Ressourcen gewährt.
  • Wenn der Zähler = 0 ist, wird der Zugriff auf gemeinsame Ressourcen verweigert.

Kurz gesagt, der Zähler verfolgt die Anzahl der Berechtigungen, die er für eine gemeinsame Ressource erteilt hat. Daher gewährt Semaphor den Threads die Erlaubnis, eine Ressource gemeinsam zu nutzen.

Charakteristika von Semaphor

Es gibt die folgenden Charakteristika eines Semaphors:

  • Es bietet Synchronisation zwischen den Threads.
  • Es verringert das Niveau der Synchronisation. Daher bietet er einen Synchronisationsmechanismus auf niedriger Ebene.
  • Der Semaphor enthält keinen negativen Wert. Er enthält einen Wert, der entweder größer als Null oder gleich Null sein kann.
  • Wir können den Semaphor mit Hilfe von Testoperationen und Interrupts implementieren, und wir verwenden die Dateideskriptoren für seine Ausführung.

Arbeitsweise des Semaphors

Der Semaphor kontrolliert die gemeinsam genutzte Ressource durch eine Zählervariable. Der Zähler ist ein nichtnegativer Wert. Er enthält einen Wert, der entweder größer als 0 oder gleich 0 ist.

  • Wenn der Zähler > 0 ist, erhält der Thread die Erlaubnis, auf die gemeinsame Ressource zuzugreifen, und der Zählerwert wird um 1 dekrementiert.
  • Andernfalls wird der Thread blockiert, bis eine Erlaubnis eingeholt werden kann.
  • Wenn die Ausführung des Threads abgeschlossen ist, wird die Ressource nicht mehr benötigt und der Thread gibt sie frei. Nach der Freigabe der Ressource wird der Zählerwert um 1 erhöht.
  • Wenn ein anderer Thread auf den Erwerb einer Ressource wartet, erhält der Thread zu diesem Zeitpunkt eine Genehmigung.
  • Wenn der Zähler = 0 ist, erhält der Thread keine Genehmigung für den Zugriff auf die gemeinsam genutzte Ressource.

Lassen Sie uns die Funktionsweise eines Semaphors mit Hilfe eines Flussdiagramms verstehen.

Java Semaphore

Arten von Semaphore

Es gibt vier Arten von Semaphore, die wie folgt sind:

  • Zählende Semaphore
  • Gegrenzte Semaphore
  • Zeitgesteuerte Semaphore
  • Binäre Semaphore

Java Semaphore

Lassen Sie uns eine nach der anderen im Detail diskutieren.

Zählende Semaphore

Die zählenden Semaphore werden verwendet, um die Situation zu lösen, in der mehr als ein Prozess gleichzeitig im kritischen Abschnitt ausgeführt werden will. Um dieses Problem zu überwinden, verwenden wir also zählende Semaphore. Betrachten wir zum Beispiel den folgenden Codeausschnitt.

Sehen wir uns die Implementierung der zählenden Semaphore an.

CountingSemaphoresExample.java

Bounded Semaphores

Wir können die obere Grenze mit Hilfe der Bounded Semaphores festlegen. Sie wird anstelle der zählenden Semaphore verwendet, da die zählenden Semaphore keinen oberen Grenzwert enthalten. Der obere Grenzwert gibt an, wie viele Signale sie speichern kann. Betrachten wir zum Beispiel den folgenden Codeausschnitt.

Sehen wir uns die Implementierung der begrenzten Semaphore an.

BoundedSemaphoresExample.java

Timed Semaphores

Die zeitgesteuerten Semaphore erlauben einem Thread, für eine bestimmte Zeit zu laufen. Nach einer bestimmten Zeit wird der Timer zurückgesetzt und gibt alle anderen Genehmigungen frei.

Lassen Sie uns die Implementierung der zeitgesteuerten Semaphoren sehen.

TimedSemaphoresExample.java

Binäre Semaphoren

Die binären Semaphoren sind die gleichen wie die zählenden Semaphoren. Aber denken Sie daran, dass sie nur binäre Werte akzeptieren, entweder 0 oder 1. Ihre Implementierung ist im Vergleich zu anderen Semaphoren einfach. Wenn der Wert 1 ist, ist die Signaloperation erfolgreich, andernfalls schlägt sie fehl.

Lassen Sie uns die Implementierung von binären Semaphore sehen.

BinarySemaphoresExample.java

Semaphore in Java

In Java ist es ein Thread-Synchronisationskonstrukt. Das Konstrukt verwendet eine Variable, die als Zähler bekannt ist und den Zugriff auf die gemeinsame Ressource steuert. Es handelt sich um einen Variablentyp, der für die Verwaltung und Synchronisierung gleichzeitiger Prozesse verwendet wird. Sie wird auch verwendet, um Wettlaufbedingungen zu vermeiden. Sie beschränkt die Anzahl der Threads, die auf eine gemeinsam genutzte Ressource zugreifen können.

Zum Beispiel können wir den Zugriff auf eine Datei auf bis zu 10 Verbindungen gleichzeitig beschränken.

Java Semaphore Klasse

Java bietet eine Semaphore Klasse, um den Semaphore Mechanismus zu implementieren. Sie gehört zum Paket java.util.concurrent. Sie implementiert die Schnittstelle Serializable. Daher ist eine manuelle Implementierung nicht erforderlich.

Die Semaphore-Klasse bietet die folgenden zwei Konstruktoren:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Sie erstellt eine Semaphore und analysiert die Anzahl der permits (anfängliche Anzahl der verfügbaren permits) als Argument. Sie gibt die Anzahl der Threads an, die sich eine Ressource gleichzeitig teilen können. Der Wert von permits kann negativ sein. In einem solchen Fall muss eine Freigabe erfolgen, bevor ein Erwerb gewährt wird.

Syntax:

Semaphore(int permits, boolean fair)

Erzeugt eine Semaphore mit der gegebenen Anzahl von Permits und den gegebenen Fairnesseinstellungen.

Syntax:

Er analysiert zwei Parameter:

  • permits: Der Wert von permits kann negativ sein. In einem solchen Fall muss die Freigabe erfolgen, bevor irgendwelche Acquires gewährt werden.
  • fair: Wenn wir den Wert auf true setzen, garantiert der Semaphor FIFO zu den Threads in der Reihenfolge, in der sie angefordert werden, false Standardmäßig gewähren alle Threads, die auf die Ressource warten, Permits in einer undefinierten Reihenfolge.

Methoden der Semaphor-Klasse

Die Klasse stellt die folgenden Methoden zur Verfügung:

acquire() Methode: Die Methode akquiriert die Permits von der Semaphore und blockiert, bis eine verfügbar ist oder der Thread unterbrochen wird. Sie reduziert die Anzahl der verfügbaren Permits um 1.

Wenn kein Permit für den aktuellen Thread verfügbar ist, wird der Thread für die Zwecke der Threadplanung deaktiviert. Der aktuelle Thread geht in den inaktiven Zustand über, bis eines von zwei Dingen passiert:

  • Wenn der andere Thread die release()-Methode aufruft, um die Ressource freizugeben, erhält der aktuelle Thread Permits.
  • Wenn der andere Thread den aktuellen Thread unterbricht.

Es wird eine InterruptedException geworfen, wenn der aktuelle Thread unterbrochen wird. Die Methode gibt keinen Wert zurück.

Syntax:

release() Methode: Sie gibt eine Permission frei und gibt sie an den Semaphor zurück. Sie erhöht die Anzahl der verfügbaren Permits um 1. Wenn ein Thread versucht, ein Permit zu erwerben, gewährt der Semaphor die Erlaubnis, die Ressource zu erwerben, die gerade von anderen Threads freigegeben wurde. Außerdem wird dieser Thread für die Threadplanung berücksichtigt.

Syntax:

availablePermits() Methode: Die Methode gibt die Anzahl der in der Semaphore verfügbaren Permits für die Gewährung der Ressource zurück. Normalerweise wird sie für Debugging- und Testzwecke verwendet.

Syntax:

Lassen Sie uns die obigen Methoden anhand eines einfachen Beispiels verstehen.

Verwendung einer Semaphore als Sperre

Java erlaubt uns die Verwendung einer Semaphore als Sperre. Das bedeutet, dass sie den Zugriff auf die Ressource sperrt. Jeder Thread, der auf die gesperrte Ressource zugreifen will, muss vor dem Zugriff auf die Ressource die Methode acquire() aufrufen, um die Sperre zu erhalten. Nach Beendigung der Aufgabe muss der Thread die Sperre durch Aufruf der release()-Methode wieder freigeben. Denken Sie daran, dass die obere Grenze auf 1 gesetzt ist. Betrachten wir zum Beispiel den folgenden Codeschnipsel:

Lassen Sie uns ein Beispiel für einen Semaphor sehen und einen Semaphor als Sperre verwenden.

SemaphoreAsLock.java

Ausgabe:

Java Semaphore

Hinweis: Wenn wir das obige Programm ausführen, erhalten wir jedes Mal eine andere Ausgabe. Ihre Ausgabe kann also von der oben gezeigten abweichen.

Java Semaphore Beispiel

Lassen Sie uns den Semaphore-Mechanismus anhand eines Java-Programms verstehen. Im folgenden Beispiel haben wir einen Konstruktor der Semaphore-Klasse mit dem anfänglichen Genehmigungswert 3 erstellt.

SemaphoreExample.java

Ausgabe:

Java Semaphore

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.