What is Semaphore in Java and its Use?

What is Semaphore in Java and its Use?
What is Semaphore in Java and its Use?

In a computing system, where resources are constrained, and multiple tasks contend for their utilisation, the concept of Process Synchronization becomes critical. This process aims to manage resource sharing among tasks in a way that maintains order and prevents conflicts. Java, through its Semaphore class, provides a mechanism to facilitate this synchronisation. 

Semaphores function as counters that help regulate access to shared resources. When a task requires a resource, it must acquire a permit from the Semaphore. If no permit is available, the task must wait until one becomes free. Once a task completes its use of the resource, it releases the permit, allowing other waiting tasks to proceed. This ensures that multiple threads can signal each other properly and safeguards critical sections of the code.

By implementing Semaphores, Java enables developers to control access to shared resources, thereby minimizing contention and preventing potential issues such as race conditions and data corruption. Through careful management of permits, Semaphores facilitate a smoother and more efficient execution of tasks in a multi-threaded environment. For individuals interested in mastering these concepts, it's advisable to explore reputable resources such as Java Training in Chennai.

What is Semaphore in Java?

In Java, a Semaphore is a synchronisation construct that facilitates controlling concurrent processes. It serves as a non-negative integer variable, representing the count of available resources. By utilising this counter, the Semaphore effectively manages shared resources, enabling threads to access them while mitigating potential problems arising from race conditions.

The primary function of a Semaphore is to coordinate access to resources among multiple threads. Threads must acquire a permit from the Semaphore to access a shared resource. If the Semaphore's count is zero, signifying unavailability, the requesting thread will be forced to wait until a resource becomes free. Once a thread finishes using the resource, it releases the permit back to the Semaphore, allowing other waiting threads to proceed.

Through this mechanism, the Semaphore acts as a guard for critical sections of code, ensuring that only one thread can access the resource at a time. This prevents data corruption or inconsistency that may arise due to concurrent access. Java's Semaphore plays a crucial role in enabling efficient resource management and synchronisation in multi-threaded environments.

What Are the Types of Semaphores?

Types of Semaphores

There are two types of Semaphore:

1. Counting Semaphore:

The counting semaphore is a synchronization construct that initializes with the number of available resources. When a process requires access to a shared resource, it invokes the wait() function, which decrements the semaphore value by 1. Once the process completes its task, it calls the signal() function, incrementing the value of the semaphore by 1. In situations where the semaphore value is 0, it indicates that no resources are currently available, causing the requesting process to enter a waiting state until a resource becomes accessible.

This mechanism helps regulate the access to shared resources, ensuring that multiple processes can use them in a controlled manner. By managing the semaphore value, the counting semaphore prevents data races and enforces mutual exclusion, guaranteeing that only one process can access a resource at any given time. The counting semaphore is a fundamental tool in managing resource sharing and preventing conflicts among concurrent processes in a multi-threaded or multi-process environment.

2. Binary Semaphore:

A binary semaphore is a synchronization primitive that can have a value of either 0 or 1. It typically begins with a value of 1. When a process seeks access to a shared resource, it can invoke the wait() function, which reduces the semaphore's value from 1 to 0, thereby signifying that the resource is currently in use. Subsequently, when the process completes its task and releases the resource, it calls the signal() function, resetting the value of the semaphore back to 1. In cases where the semaphore value is 0, it indicates that the resource is currently being used, and any requesting process must wait until the resource becomes available again.

Binary semaphores are particularly useful for situations where mutual exclusion is necessary, ensuring that only one process can access a resource at any given time. This mechanism prevents race conditions and ensures that critical sections of code are protected from simultaneous access by multiple processes. Binary semaphores play a vital role in managing shared resources in multi-threaded or multi-process environments, thereby maintaining the integrity and consistency of data accessed by different processes. For those seeking to delve deeper into the intricacies of Java, considering a comprehensive educational program such as a Java Course in Pondicherry could be highly advantageous.

How Does a Semaphore Work?

Semaphore Work

The semaphore's counter has a value of 0 or more.

  • When the counter is greater than 0, a thread is allowed to use the shared resource, and the counter decreases by 1.
  • If the counter is 0, a thread attempting to access the resource gets blocked, waiting until a permit becomes available.
  • After a thread finishes using the resource, it releases the resource, causing the counter to increase by 1.
  • Consequently, a waiting thread can acquire a permit to use the resource.

Access to the resource is denied if the counter is 0, which indicates that all permits are currently held by other threads.

This mechanism allows for controlled access to shared resources, preventing data races and ensuring that critical sections of code are accessed by only one thread at a time. By managing the semaphore's counter, concurrent threads can effectively coordinate resource access, thereby avoiding conflicts and maintaining data integrity in multi-threaded or multi-process environments.

Timed Semaphore, Semaphore vs. Mutex

Timed Semaphore:

A timed semaphore is a synchronization primitive that permits a thread to operate for a predetermined duration. Unlike traditional semaphores, which primarily regulate access to shared resources, a timed semaphore automatically releases all permissions associated with the semaphore once the specified time has elapsed. This functionality ensures that threads can execute their tasks within a predefined time window, preventing potential issues that might arise from prolonged or indefinite resource acquisition.

The timed semaphore's ability to reset the timer after each execution cycle allows for systematic control over the time allocated to each thread. By enforcing time limits, this type of semaphore helps manage resource utilization, prevents deadlock scenarios, and ensures that threads do not monopolize shared resources indefinitely. Timed semaphores are particularly beneficial in scenarios where resource allocation needs to be time-bound and where ensuring timely execution is crucial to maintaining the overall performance and stability of the system. For individuals in Madurai looking to expand their Java expertise, exploring a reputable educational resource such as a Java Course in Madurai could be a valuable step forward.

Semaphore vs. Mutex:

Semaphore:

 Allows multiple processes to access a shared resource until it's unavailable.

 It's a variable greater than 0.

 Deploys a signal mechanism using the wait() and signal() methods to indicate resource usage.

 Multiple processes can change the value, but only one can modify it at a time to acquire a resource.

Mutex:

  • Allows multiple processes to access a resource, but only one at a time.
  • It's an object.
  • Deploys a locking mechanism, where a process locks and releases the resource.
  • The same process can acquire or release a lock at a time.

Implementation of Semaphore


import java.util.concurrent.*;

// Shared Resource class

class Resource {

static int count = 0;

}

// Thread class

class MyDemo extends Thread {

Semaphore sem;

String threadName;

public MyDemo(Semaphore sem, String threadName) {

super(threadName);

this.sem = sem;

this.threadName = threadName;

}

@Override

public void run() {

// Thread X

if (this.getName().equals("X")) {

System.out.println("Starting " + threadName);

try {

System.out.println(threadName + " awaiting permit.");

sem.acquire();

System.out.println(threadName + " received a permit.");

for (int i = 0; i < 7; i++) {

Resource.count++;

System.out.println(threadName + ": " + Resource.count);

Thread.sleep(20);

}

} catch (InterruptedException exc) {

System.out.println(exc);

}

System.out.println(threadName + " released permit.");

sem.release();

}

// Thread Y

else {

System.out.println("Starting " + threadName);

try {

System.out.println(threadName + " awaiting permit.");

sem.acquire();

System.out.println(threadName + " received a permit.");

for (int i = 0; i < 7; i++) {

Resource.count--;

System.out.println(threadName + ": " + Resource.count);

Thread.sleep(20);

}

} catch (InterruptedException exc) {

System.out.println(exc);

}

System.out.println(threadName + " released permit.");

sem.release();

}

}

}

// Main Class

public class SemTest {

public static void main(String args[]) throws InterruptedException {

Semaphore sem = new Semaphore(1); // creating a Semaphore object with number of permits 1

MyDemo md1 = new MyDemo(sem, "X"); // creating threads X and Y

MyDemo md2 = new MyDemo(sem, "Y");

md1.start(); // starting threads X and Y

md2.start();

md1.join(); // waiting for threads X and Y

md2.join();

System.out.println("count: " + Resource.count);

}

}

Output


Starting X

Starting Y

X awaiting permit

Y awaiting permit

X:1

X:2

X:3

X:4

X:5

X:6

X:7

X released permit

Y received a permit

Y:6

Y:5

Y:4

Y:3

Y:2

Y:1

Y:0

Y released permit

count:0

In Java, Mutex and Semaphore are both mechanisms used to achieve process synchronization. Mutex is a mutually exclusive object that regulates access to a resource, ensuring that only one thread can access the resource at any given time by entering the critical section. Once the thread exits the critical section, the resource is released. Conversely, Semaphore, which also serves as a means of process synchronization, employs a signaling mechanism using a non-negative counter variable to coordinate signals between threads that require access to a shared resource. For those looking to deepen their understanding of these concepts, it's advisable to consider exploring a reliable educational resource such as a Java Course in Bangalore.

This article delves into the concept of Semaphore in Java and its practical applications. If you're seeking to enhance your skills, we suggest considering FITA Academy’s Program in Full Stack Web Development course in Chennai. This comprehensive course can assist you in refining your Java skills, preparing you for potential employment opportunities with HIRIST and HackerEarth. Upon successful completion, you may be eligible for a job guarantee with an average salary of 2.5 to 7 LPA. For those residing in Coimbatore, exploring a reliable educational resource such as a Java Course in Coimbatore could also be beneficial.

Interview Questions


FITA Academy Branches

Chennai

TRENDING COURSES

Digital Marketing Online Course Software Testing Online Course Selenium Online Training Android Online Training Swift Developer Online Course RPA Training Online AWS Online Training DevOps Online Training Cyber Security Online Course Ethical Hacking Online Course Java Online Course Full Stack Developer Online Course Python Online Course PHP Online Course Dot Net Online Training

AngularJS Online Course Data Science Online Course Artificial Intelligence Online Course Graphic Design Online Training Spoken English Course Online German Online Course IELTS Online Coaching Digital Marketing Course in Chennai Software Testing Training in Chennai Selenium Training in Chennai Swift Developer Course in Chennai RPA Training in Chennai AWS Training in Chennai DevOps Training In Chennai Ethical Hacking Course in Chennai Java Training In Chennai Python Training In Chennai PHP Training in Chennai AngularJS Training In Chennai Cyber Security Course in Chennai Full Stack Developer Course in Chennai UI UX Design Course in Chennai Data Science Course in Chennai Dot Net Training In Chennai Salesforce Training in Chennai Hadoop Training in Chennai Android Training in Chennai Tally Training in Chennai Artificial Intelligence Course in Chennai Graphic Design Courses in Chennai Spoken English Classes in Chennai German Classes in Chennai IELTS Coaching in Chennai Java Training in Bangalore Python Training in Bangalore IELTS Coaching in Bangalore Software Testing Course in Bangalore Selenium Training in Bangalore Digital Marketing Courses in Bangalore AWS Training in Bangalore Data Science Courses in Bangalore Ethical Hacking Course in Bangalore CCNA Course in Bangalore Spoken English Classes in Bangalore German Classes in Bangalore

Read more