Java Counting Semaphore behält eine bestimmte Anzahl von Durchgängen oder Berechtigungen bei, und der aktuelle Thread muss eine Genehmigung erhalten, um auf eine gemeinsam genutzte Ressource zuzugreifen. Wenn eine Genehmigung bereits durch andere Threads erschöpft ist, kann sie warten, bis die Genehmigung als Ergebnis der Freigabe von Genehmigungen von verschiedenen Threads verfügbar wird. Dieses Parallelitätsdienstprogramm kann sehr nützlich sein, um ein Producer-Consumer-Designmuster oder begrenzte Pools von Assets wie Thread-Pool, DB-Verbindungspool usw. zu implementieren. Die Klasse java.util.Semaphore ist ein zählendes Semaphor, das mit einer Zahl initialisiert wird von Berechtigungen. 

How to Use Counting Semaphore in Concurrent Java Application?

Semaphore bietet zwei Hauptmethoden zum Erhalten von Genehmigungen und zum Freigeben von Genehmigungen

  • erwerben( ): Diese Methode erwirbt eine Genehmigung, falls eine verfügbar ist, und kehrt sofort zurück, wobei die Anzahl der verfügbaren Genehmigungen um eins reduziert wird. Wenn der aktuelle Thread beim Warten auf eine Genehmigung unterbrochen wird, wird InterruptedException ausgelöst.
  • release() : Diese Methode erwirbt die angegebene Anzahl von Genehmigungen, falls sie verfügbar sind, und kehrt sofort zurück, wobei die Anzahl der verfügbaren Genehmigungen um den angegebenen Betrag reduziert wird. Wenn der aktuelle Thread beim Warten auf eine Genehmigung unterbrochen wird, wird InterruptedException ausgelöst.

Implementierung:

Ein binäres Semaphor wird als Zählsemaphor mit einer Genehmigung bezeichnet, da es nur zwei staatliche Genehmigungen verfügbar oder nicht verfügbare Genehmigungen gibt. Um einen gegenseitigen Ausschluss oder einen kritischen Abschnitt auszuführen, in dem nur ein Thread ausgeführt werden darf, kann ein binäres Semaphor verwendet werden. Ein Thread wartet auf „acquire()“, bis Thread die Freigabe innerhalb des kritischen Abschnitts zulässt, indem er „release()“ auf dem Semaphor aufruft. Unten ist die Java-Semaphor-Zählung aufgeführt, bei der binäre Semaphore verwendet werden, um gemeinsamen exklusiven Zugriff auf wesentliche Codeteile bereitzustellen

Beispiel:

Java

// Java Program to illustrate use Counting Semaphore
// in Concurrent Java Application
 
import java.util.concurrent.Semaphore;
 
public class SemaphoreTest {
 
    // Initialize the semaphore with the number
    // of permits required
 
    // Here only 1 permit is allowed
    Semaphore binary = new Semaphore(1);
 
    // Main driver method
    public static void main(String args[])
    {
 
        final SemaphoreTest test = new SemaphoreTest();
 
        // Thread 1
        new Thread() {
           
            // Method that should be executed for thread1
            @Override public void run()
            {
                test.mutualExclusion();
            }
        }.start();
 
        // Thread 2
        new Thread() {
           
            // Method that should be executed for thread2
            @Override public void run()
            {
                test.mutualExclusion();
            }
        }.start();
    }
 
    // Method
    private void mutualExclusion()
    {
 
        // Try block to check for exceptions
        try {
            // acquire() acts as an input to semaphore
            // to check for available permits
            binary.acquire();
 
            // Mutual exclusive region
 
            System.out.println(
                Thread.currentThread().getName()
                + " inside mutual exclusive ");
 
            // sleep() method is used to hold thread for
            // sometime Parameter is nanoseconds to be
            // holded
            Thread.sleep(1000);
        }
 
        // Catch block to handle the exception
 
        // Handling exception if thread is interrupted
        // either before or during the activity
        catch (InterruptedException e) {
 
            // Print and display the line number where
            // exception occured
            e.printStackTrace();
        }
 
        finally {
 
            // release() method acts as output to semaphore
            // When thread operation is completed
            // release() method increase the permits
            // in the semaphore
            binary.release();
 
            // Printing the thread name
            // using the getName() method
            System.out.println(
                Thread.currentThread().getName()
                + " outside of mutual exclusive ");
        }
    }
}
Ausgabe
Thread-0 innerhalb gegenseitig ausschließend
Thread-1 schließt sich gegenseitig aus
Thread-0 außerhalb von gegenseitigem Ausschluss
Thread-1 außerhalb von gegenseitigem Ausschluss