Semaphore in Java

Category: Java   Tags: Java, Java Thread, Java MultiThread, Thread Synchronization, Java Semaphore, Java Concurrent Collection

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.

How It Works?

  1. To use a semaphore, the thread that wants access to the shared resource tries to acquire a permit.
  2. If the semaphore’s count is greater than zero, then the thread acquires a permit, that causes the semaphore’s count to be decremented else the thread will be blocked until a permit can be acquired.
  3. When the thread is done with all its purpose to the shared resource, it releases the permit, which causes the semaphore’s count to be incremented.
  4. If there is another thread waiting for a permit, then that thread will acquire a permit at that time.

Java support semaphore using Semaphore class. It has the two constructors shown here:

                                Semaphore(int permitCount)
                                Semaphore(int permitCount, boolean inOrder)
                              

permitCount specifies the number of threads that can access a shared resource at any one time. If inOrder is true, waiting threads are granted a permit in the order in which they requested access. Semaphore has two methods:

Use acquire method to acquire a permit. It has two constructors:

                                void acquire() throws InterruptedException
                                void acquire(int numberOfPermit) throws InterruptedException
                              

The first form acquires one permit. The second form acquires numberOfPermit permits.

Use release method to release a permit. It has two constructors:

                                void release() throws InterruptedException
                                void release(int numberOfPermit) throws InterruptedException
                              

The first form release one permit. The second form release numberOfPermit permits. Here is one simple Java example:

JavaSemaphoreExample.java

                            package com.tutorial.javabasic;

                            import java.util.concurrent.Semaphore;

                            class Counter {
                                static int count = 0;
                            }

                            class Thread1 implements Runnable {

                                private Semaphore semaphore;

                                Thread1(Semaphore s) {
                                    semaphore = s;
                                    new Thread(this).start();
                                }

                                @Override
                                public void run() {
                                    System.out.println("Thread1 is waiting to acquire the permit.");
                                    try {
                                        semaphore.acquire();
                                    } catch (InterruptedException ex) {
                                        ex.printStackTrace();
                                    }
                                    System.out.println("Thread1 got the permit.");
                                    for (int i = 1; i <= 5; i++) {
                                        Counter.count++;
                                        System.out.println(Counter.count);
                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException ex) {
                                            ex.printStackTrace();
                                        }
                                    }
                                    semaphore.release();
                                    System.out.println("Thread1 releases the permit.");
                                }
                            }

                            class Thread2 implements Runnable {

                                private Semaphore semaphore;

                                Thread2(Semaphore s) {
                                    semaphore = s;
                                    new Thread(this).start();
                                }

                                @Override
                                public void run() {
                                    System.out.println("Thread2 is waiting to acquire the permit.");
                                    try {
                                        semaphore.acquire();
                                    } catch (InterruptedException ex) {
                                        ex.printStackTrace();
                                    }
                                    System.out.println("Thread2 got the permit.");
                                    for (int i = 1; i <= 5; i++) {
                                        Counter.count++;
                                        System.out.println(Counter.count);
                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException ex) {
                                            ex.printStackTrace();
                                        }
                                    }
                                    semaphore.release();
                                    System.out.println("Thread1 releases the permit.");
                                }
                            }

                            public class JavaSemaphoreExample {

                                public static void main(String s[]) {
                                    Semaphore semaphore = new Semaphore(1);
                                    new Thread1(semaphore);
                                    new Thread2(semaphore);
                                }
                            }
                        

Output:

                            Thread1 is waiting to acquire the permit.
                            Thread2 is waiting to acquire the permit.
                            Thread1 got the permit.
                            1
                            2
                            3
                            4
                            5
                            Thread1 releases the permit.
                            Thread2 got the permit.
                            6
                            7
                            8
                            9
                            10
                            Thread1 releases the permit.
                          

Here semaphore is used to control the access to shared resource which is a static variable in this case. Output of this program shows that even after calling sleep first thread do not get interfered by second thread. Once the first thread release the permit then only second thread is allowed to get the permit.