Javatpoint Logo
Javatpoint Logo

Java Semaphore

In Java, we use semaphore in the thread synchronization. It is used to control access to a shared resource that uses a counter variable. Java also provides a Semaphore class that contains constructors and various methods to control access over the shared resource. We will discuss it later in this section.

Before moving ahead in this section, first, we will understand what is semaphore, types of semaphore, how it works, and how to implement semaphore. After knowing all about it, we will move to the Java semaphore programs.

What is a semaphore?

A Semaphore is used to limit the number of threads that want to access a shared resource. In other words, it is a non-negative variable that is shared among the threads known as a counter. It sets the limit of the threads. A mechanism in which a thread is waiting on a semaphore can be signaled by other threads.

  • If counter > 0, access to shared resources is provided.
  • If counter = 0, access to shared resources is denied.

In short, the counter keeps tracking the number of permissions it has given to a shared resource. Therefore, semaphore grants permission to threads to share a resource.

Characteristics of Semaphore

There are the following characteristics of a semaphore:

  • It provides synchronization among the threads.
  • It decreases the level of synchronization. Hence, provides a low-level synchronization mechanism.
  • The semaphore does not contain a negative value. It holds a value that may either greater than zero or equal to zero.
  • We can implement semaphore using the test operation and interrupts, and we use the file descriptors for executing it.

Working of Semaphore

Semaphore controls over the shared resource through a counter variable. The counter is a non-negative value. It contains a value either greater than 0 or equal to 0.

  • If counter > 0, the thread gets permission to access the shared resource and the counter value is decremented by 1.
  • Else, the thread will be blocked until a permit can be acquired.
  • When the execution of the thread is completed then there is no need for the resource and the thread releases it. After releasing the resource, the counter value incremented by 1.
  • If another thread is waiting for acquiring a resource, the thread will acquire a permit at that time.
  • If counter = 0, the thread does not get permission to access the shared resource.

Let's understand the working of semaphore with the help of a flow chart.

Java Semaphore

Types of Semaphores

There are four types of semaphores, which are as follows:

  • Counting Semaphores
  • Bounded Semaphores
  • Timed Semaphores
  • Binary Semaphores
Java Semaphore

Let's discuss one by one in detail.

Counting Semaphores

The counting semaphores are used to resolve the situation in which more than one process wants to execute in the critical section, simultaneously. Hence to overcome this problem we use counting semaphore. For example, consider the following code snippet.

Let's see the implementation of the counting semaphores.

Bounded Semaphores

We can set the upper bound limit using the bounded semaphores. It is used in place of the counting semaphores because the counting semaphores do not contain any upper bound value. The upper bound value denotes how many signals it can store. For example, consider the following code snippet.

Let's see the implementation of the bounded semaphore.

Timed Semaphores

The timed semaphores allow a thread to run for a specified period of time. After a particular time, the timer resets and releases all other permits.

Let's see the implementation of the timed semaphores.

Binary Semaphores

The binary semaphores are the same as counting semaphores. But remember that it accepts only binary values either 0 or 1. Its implementation is easy in comparison to other semaphores. If the value is 1, the signal operation is success, fails otherwise.

Let's see the implementation of binary semaphores.

Semaphore in Java

In Java, it is a thread synchronization construct. The construct uses a variable known as a counter that controls access over the shared resource. It is a type of variable which is used to manage concurrent processes and also synchronize them. It is also used to avoid race conditions. It restricts the number of threads to access a shared resource.

For example, we can restrict a file to access up to 10 connections simultaneously.

Java Semaphore Class

Java provides a Semaphore class to implement the semaphore mechanism. It belongs to the java.util.concurrent package. It implements the Serializable interface. Hence, manual implementation is not required.

The Semaphore class provides the following two constructors:

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

Semaphore(int permits)

It creates a Semaphore and parses the number of permits (initial number of permits available) as an argument. It specifies the number of threads that can share a resource at a time. The value of permits may be negative. In such a case, a release must occur before any acquires will be granted.


Semaphore(int permits, boolean fair)

It creates a Semaphore with the given number of permits and the given fairness settings.


It parses two parameters:

  • permits: The value of permits may be negative. In such a case, the release must occur before any acquires will be granted.
  • fair: If we set the value to true, the semaphore guarantees FIFO to the threads in the order they are requested, false By default, all the threads that are waiting for the resource grants permit in an undefined order.

Methods of the Semaphore Class

The class provides the following methods:

acquire() Method: The method acquire the permits from the semaphore, blocking until one is available, or the thread is interrupted. It reduces the number of available permits by 1.

If there is no permit is available for the current thread, the thread becomes disabled for the thread scheduling purposes. The current thread goes in the inactive state until one of two things happens:

  • If the other thread invokes the release() method to release the resource then the current thread gets permits.
  • If the other thread interrupts the current thread.

It throws InterruptedException if the current thread is interrupted. The method does not return any value.


release() Method: It releases a permit and returns it to the semaphore. It increments the number of available permits by 1. If a thread tries to acquire a permit, the semaphore grants permission to acquire the resource that was just released by other threads. Further, that thread is considered for thread scheduling purposes.


availablePermits() Method: The method returns the number of permits available in semaphore for granting the resource. Usually, it is used for debugging and testing purposes.


Let's understand the above methods through a simple example.

Using Semaphore as Lock

Java allows us to use a semaphore as a lock. It means, it locks the access to the resource. Any thread that wants to access the locked resource, must call the acquire() method before accessing the resource to acquire the lock. The thread must release the lock by calling the release() method, after the completion of the task. Remember that set the upper bound to 1. For example, consider the following code snippet:

Let's see an example of a semaphore and use semaphore as a lock.


Java Semaphore

Note: When we execute the above program, we get different output every time. So, your output may differ from the output shown above.

Java Semaphore Example

Let's understand the semaphore mechanism through a Java program. In the following example, we have created a constructor of the Semaphore class with the initial permit value 3.


Java Semaphore
Next TopicJava Array to List

Youtube For Videos Join Our Youtube Channel: Join Now


Help Others, Please Share

facebook twitter pinterest

Learn Latest Tutorials


Trending Technologies

B.Tech / MCA