Semaphore

Java-Semaphore

Semaphore

The java.util.concurrent package adds several higher-level synchronization utilities borrowed from other languages. Semaphore is one of the higher-level synchronization constructs. Semaphores are a very old synchronization construct that has been used in many other languages. Conceptually, a semaphore is a pool of permits—intangible permission slips to perform some activity. The semaphore is initialized with a specified number of permits. Callers can then use the acquire() and release() methods to take and return these permits. Calling acquire() when no permits are available causes the caller to block until one is released.

Semaphore

A semaphore controls access to a shared resource through the use of a counter. If the counter is greater than zero, then access is allowed. If it is zero, then access is denied. What the counter is counting are permits that allow access to the shared resource. Thus, to access the resource, a thread must be granted a permit from the semaphore.

In general, to use a semaphore, the thread that wants access to the shared resource tries to acquire a permit. If the semaphore’s count is greater than zero, then the thread acquires a permit, which causes the semaphore’s count to be decremented. Otherwise, the thread will be blocked until a permit can be acquired. When the thread no longer needs access to the shared resource, it releases the permit, which causes the semaphore’s count to be incremented. If there is another thread waiting for a permit, then that thread will acquire a permit at that time. Java’s Semaphore class implements this mechanism.

Semaphore

Semaphore has the two constructors :

Semaphore

Here, num specifies the initial permit count. Thus, num specifies the number of threads that can access a shared resource at any one time. If num is two, then only two threads can access the resource at any one time. By default, waiting threads are granted a permit in an undefined order. By setting fair to true, you can ensure that waiting threads are granted a permit in the order(first-in-first-out) in which they requested access. To acquire a permit, call the acquire( ) methods :

Semaphore

The first form acquires one permit. The second form acquires num permits. Most often, the first form is used. If the permit cannot be granted at the time of the call, then the invoking thread suspends until the permit is available. The “pool of permits” is really just a number. No actual value is returned by acquire() and no association is made with the callers. It means that “permits” can be acquired and released by different callers without respect to who actually “acquired” them. It’s really just incrementing or decrementing the number. That is, if a thread calls acquire() multiple times, it simply decrements the counter multiple times. To release a permit, call the release( ) methods :

Semaphore

The first form releases one permit. The second form releases the number of permits specified by num. To use a semaphore to control access to a resource, each thread that wants to use that resource must first call acquire( ) before accessing the resource. When the thread is done with the resource, it must call release( ). Finally, because the permits pool is really just a number, calling acquire() and release() out of sync can increase the permit pool beyond its starting point or decrement it below zero. It can even be initialized with a negative number if you wish to require releases before anyone acquires a permit.

Program

Semaphore


Semaphore

Program Explanation

This program uses a semaphore to control access to the data array and intex variable, which are static. The intex is incremented three times and three values from the data array are prints by the run() method of MyClass. To prevent multible threads from accessing data array and intex at the same time, access is allowed only after a permit is acquired from the controlling semaphore. After access is complete, the permit is released. In this way, only one thread at a time will access data array and index.

Notice the call to sleep( ) within run( ). It is used to “prove” that accesses to intex and data array are synchronized by the semaphore. In run( ), the call to sleep( ) causes the invoking thread to pause between each access to data array and index. This would normally enable the another threads to run. However, because of the semaphore, another threads must wait until the first has released the permit, which happens only after all accesses by the first thread are complete. Thus, multible threads not access the data array and index in same time and not intermixed. This ensures by samasphore.

Without the use of the semaphore, accesses to the data array and intex by multible threads would have occurred simultaneously, it would be intermixed. To confirm this, try commenting out the calls to acquire( ) and release( ). When you run the program, you will see that access to the data array and intex are no longer synchronized, and each thread accesses it as soon as it gets a timeslice.

Semaphore
Program Source

import java.util.concurrent.Semaphore;

class MyClass extends Thread {

    static int data[] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
    static int intex;
    Semaphore sm;

    MyClass(Semaphore s) {
        sm = s;
    }

    public void run() {

        System.out.println(Thread.currentThread().getName() + "-->Waiting for permit...");
        try {
            sm.acquire();
            System.out.println(Thread.currentThread().getName() + "-->Gets a permit");

            for (int i = 0; i < 3; i++) {                 System.out.println("data["+intex+"]-->"+data[intex]);
                intex++;
                Thread.sleep(1000);
            }
        } catch (InterruptedException i){};
        sm.release();
        System.out.println(Thread.currentThread().getName() + "-->Releases the permit...");
    }
}

public class Javaapp {

    public static void main(String[] args) {

        Semaphore sm = new Semaphore(1);
        new MyClass(sm).start();
        new MyClass(sm).start();
        new MyClass(sm).start();
    }
}

Leave a Comment