# Using Semaphore to Protect More than One Copy of a Resource in Java

• Last Updated : 04 Aug, 2022

A semaphore work on the concepts of permits. A semaphore is initialized with a certain number of permits. The number of permits is equal to the number of shared resources available. When a thread wants to access a shared resource, it acquires the permit and when done accessing the shared resource, it releases the permit.

Illustration:

Illustration 1: Restaurant application having 10 tables.

There are 20 people standing outside the restaurant, waiting to enter. In this case, the number of semaphores is the same as the number of resources(tables) which is 10. For any customer to enter the restaurant, he has to acquire a permit. After acquiring the permit, he chooses one of the available tables. Once his order is completed he releases the semaphore making it available for other customers waiting in the queue. Thus semaphore ensures that at a time only 10 customers can enter the restaurant and make orders.

Illustration 2: People waiting in a queue at an ATM center.

If there are 2 ATM machines, at a time only 2 people can access the ATM machine and withdraw money. When a customer enters the ATM center, he acquires a permit if available, then checks which of the ATM machines is free for use. Once he gets an available ATM machine, he locks it and then enters the PIN and withdraws money. After withdrawing, he releases the lock on the ATM machine and also releases the semaphore. The reason he has to lock the ATM machine before withdrawing money is if 2 people after acquiring the semaphore end up in the same ATM machine. Here the ATM machine is a shared resource and the number of semaphores is equal to the number of ATM machines.

Working of a semaphore is as follows:

For our restaurant application, we initialize our semaphore with 10 permits which are equal to the number of tables available. If there are 30 customers in the queue waiting to enter the restaurant, Customer 1 acquires a permit, enters the restaurant. When a customer enters the restaurant, he acquires a permit and chooses 1 out of 10 available tables. Letâ€™s suppose that customer #1 chooses table # 5. The number of available permits is 9. Customer # 2 acquires another permit since permits are still available and chooses table # 7. In this way, 10 customers can acquire permits and choose the unoccupied tables. When customer # 11 enters the restaurant, he is blocked until one of the 10 customers releases the semaphore and leaves the table.

Example:

## Java

 `// Java Program to Use a Semaphore to Protect more than One``// Copy of a Resource` `// Importing input output classes``import` `java.io.*;``// Importing utility classes``import` `java.util.Arrays;``import` `java.util.concurrent.Semaphore;` `// Class 1``// Helper class 1``class` `ATMQueue {` `    ``// Member variables``    ``private` `Semaphore semaphore;``    ``private` `boolean``[] freeAtms;` `    ``// Method 1``    ``public` `ATMQueue()``    ``{` `        ``semaphore = ``new` `Semaphore(``2``);``        ``freeAtms = ``new` `boolean``[``2``];``        ``Arrays.fill(freeAtms, ``true``);``    ``}` `    ``// Method 2``    ``public` `void` `withDrawMoney()``    ``{` `        ``// Try block to check for exceptions``        ``try` `{` `            ``// Try to acquire a semaphore.``            ``// If none are available, thread will block here``            ``// till a semaphore becomes available``            ``semaphore.acquire();` `            ``// Check for available ATM machine``            ``int` `atmMachine = getAvailableATM();` `            ``// since atm Machine is available to withdraw``            ``// money, we acquire a semaphore``            ``System.out.println(``                ``Thread.currentThread().getName()``                ``+ ``":-Withdrawing money from atm number :-"``                ``+ atmMachine);` `            ``System.out.println(``                ``"---------------------------------"``);` `            ``Thread.sleep((``long``)(Math.random() * ``1000``));` `            ``System.out.println(``                ``Thread.currentThread().getName()``                ``+ ``":-done withdrawing money"``);` `            ``releaseATM(atmMachine);` `            ``System.out.printf(``                ``"ATM machine :- %s is now available"``,``                ``atmMachine);` `            ``System.out.println(``                ``"---------------------------------"``);` `            ``System.out.println(``                ``"About to release the semaphore"``);` `            ``semaphore.release();` `            ``System.out.println(``"Semaphore released"``);``        ``}` `        ``// catch block to handle the exceptions``        ``catch` `(InterruptedException e) {` `            ``// Print the exceptions along with line number``            ``e.printStackTrace();``        ``}``    ``}` `    ``// Method 3``    ``private` `void` `releaseATM(``int` `atmNumber)``    ``{` `        ``// We are making specific atm machine free for use``        ``synchronized` `(freeAtms)``        ``{``            ``freeAtms[atmNumber] = ``true``;``        ``}``    ``}` `    ``// Method 4``    ``private` `int` `getAvailableATM()``    ``{``        ``int` `freeAtm = -``1``;` `        ``// We are using synchronized to ensure that only 1``        ``// thread can access and modify the shared boolean``        ``// array freeAtms``        ``synchronized` `(freeAtms)``        ``{` `            ``for` `(``int` `i = ``0``; i < freeAtms.length; i++) {` `                ``if` `(freeAtms[i]) {``                    ``freeAtms[i] = ``false``;``                    ``freeAtm = i;` `                    ``break``;``                ``}``            ``}``        ``}` `        ``return` `freeAtm;``    ``}``}` `// Class 2``// Helper class 2``class` `WithdrawMoneyTask ``implements` `Runnable {` `    ``private` `ATMQueue atmQueue;` `    ``public` `WithdrawMoneyTask(ATMQueue atmQueue)``    ``{``        ``// TODO Auto-generated constructor stub``        ``this``.atmQueue = atmQueue;``    ``}` `    ``@Override` `public` `void` `run()``    ``{``        ``System.out.println(``            ``Thread.currentThread().getName()``            ``+ ``": - about to withdraw money after acquiring the permit"``);` `        ``atmQueue.withDrawMoney();``    ``}``}` `// Class 3``// Main class``class` `GFG {` `    ``// Main  driver method``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``// Print statement``        ``System.out.println(``"GFG!"``);` `        ``// Creating an object of class 1 in main() method``        ``ATMQueue atmQueue = ``new` `ATMQueue();` `        ``// Creating Thread class object``        ``Thread thread[] = ``new` `Thread[``10``];` `        ``for` `(``int` `i = ``0``; i < ``10``; i++) {``            ``thread[i] = ``new` `Thread(``                ``new` `WithdrawMoneyTask(atmQueue),``                ``"Thread "` `+ i);``        ``}` `        ``for` `(``int` `i = ``0``; i < ``10``; i++) {``            ``thread[i].start();``        ``}``    ``}``}`

## Java

 `// Java Program to Use a Semaphore to Protect more than One``// Copy of a Resource` `// Importing input output classes``import` `java.io.*;``// Importing utility classes``import` `java.util.Arrays;``import` `java.util.concurrent.Semaphore;` `// Class 1``// Helper class 1``class` `ATMQueue {` `    ``// Member variables``    ``private` `Semaphore semaphore;``    ``private` `boolean``[] freeAtms;` `    ``// Method 1``    ``public` `ATMQueue()``    ``{` `        ``semaphore = ``new` `Semaphore(``2``);``        ``freeAtms = ``new` `boolean``[``2``];``        ``Arrays.fill(freeAtms, ``true``);``    ``}` `    ``// Method 2``    ``public` `void` `withDrawMoney()``    ``{` `        ``// Try block to check for exceptions``        ``try` `{` `            ``// Try to acquire a semaphore.``            ``// If none are available, thread will block here``            ``// till a semaphore becomes available``            ``semaphore.acquire();` `            ``// Check for available ATM machine``            ``int` `atmMachine = getAvailableATM();` `            ``// since atm Machine is available to withdraw``            ``// money, we acquire a semaphore``            ``System.out.println(``                ``Thread.currentThread().getName()``                ``+ ``":-Withdrawing money from atm number :-"``                ``+ atmMachine);` `            ``System.out.println(``                ``"---------------------------------"``);` `            ``Thread.sleep((``long``)(Math.random() * ``1000``));` `            ``System.out.println(``                ``Thread.currentThread().getName()``                ``+ ``":-done withdrawing money"``);` `            ``releaseATM(atmMachine);` `            ``System.out.printf(``                ``"ATM machine :- %s is now available"``,``                ``atmMachine);` `            ``System.out.println(``                ``"---------------------------------"``);` `            ``System.out.println(``                ``"About to release the semaphore"``);` `            ``semaphore.release();` `            ``System.out.println(``"Semaphore released"``);``        ``}` `        ``// catch block to handle the exceptions``        ``catch` `(InterruptedException e) {` `            ``// Print the exceptions along with line number``            ``e.printStackTrace();``        ``}``    ``}` `    ``// Method 3``    ``private` `void` `releaseATM(``int` `atmNumber)``    ``{` `        ``// We are making specific atm machine free for use``        ``synchronized` `(freeAtms)``        ``{``            ``freeAtms[atmNumber] = ``true``;``        ``}``    ``}` `    ``// Method 4``    ``private` `int` `getAvailableATM()``    ``{``        ``int` `freeAtm = -``1``;` `        ``// We are using synchronized to ensure that only 1``        ``// thread can access and modify the shared boolean``        ``// array freeAtms``        ``synchronized` `(freeAtms)``        ``{` `            ``for` `(``int` `i = ``0``; i < freeAtms.length; i++) {` `                ``if` `(freeAtms[i]) {``                    ``freeAtms[i] = ``false``;``                    ``freeAtm = i;` `                    ``break``;``                ``}``            ``}``        ``}` `        ``return` `freeAtm;``    ``}``}` `// Class 2``// Helper class 2``class` `WithdrawMoneyTask ``implements` `Runnable {` `    ``private` `ATMQueue atmQueue;` `    ``public` `WithdrawMoneyTask(ATMQueue atmQueue)``    ``{``        ``// TODO Auto-generated constructor stub``        ``this``.atmQueue = atmQueue;``    ``}` `    ``@Override` `public` `void` `run()``    ``{``        ``System.out.println(``            ``Thread.currentThread().getName()``            ``+ ``": - about to withdraw money after acquiring the permit"``);` `        ``atmQueue.withDrawMoney();``    ``}``}` `// Class 3``// Main class``class` `GFG {` `    ``// Main  driver method``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``// Print statement``        ``System.out.println(``"GFG!"``);` `        ``// Creating an object of class 1 in main() method``        ``ATMQueue atmQueue = ``new` `ATMQueue();` `        ``// Creating Thread class object``        ``Thread thread[] = ``new` `Thread[``10``];` `        ``for` `(``int` `i = ``0``; i < ``10``; i++) {``            ``thread[i] = ``new` `Thread(``                ``new` `WithdrawMoneyTask(atmQueue),``                ``"Thread "` `+ i);``        ``}` `        ``for` `(``int` `i = ``0``; i < ``10``; i++) {``            ``thread[i].start();``        ``}``    ``}``}`

Output

```GFG!
Thread 4:-Withdrawing money from atm number :-1
---------------------------------
Thread 7:-Withdrawing money from atm number :-0
---------------------------------
ATM machine :- 0 is now available---------------------------------
Semaphore released
Thread 9:-Withdrawing money from atm number :-0
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 2:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 0 is now available---------------------------------
Semaphore released
Thread 8:-Withdrawing money from atm number :-0
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 0:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 1:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 5:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 3:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 1 is now available---------------------------------
Semaphore released
Thread 6:-Withdrawing money from atm number :-1
---------------------------------
ATM machine :- 0 is now available---------------------------------
Semaphore released
ATM machine :- 1 is now available---------------------------------
Semaphore released```

Also, the real-time output is appended due to the occurrence of semaphore leading to concurrency in the execution of our program.

Output explanation:

• In this code example, there are 3 classes. WithdrawMoneyTask class defines the job/task to be executed.  So it implements the Runnable interface.
• It has a private member ATMQueue which represents an ATM machine. We call it’s withdrawMoney() method.
• In ATMQueue class, we have 2 member variables. The member variable semaphore is defined in the constructor. It is initialized to 2 because there are only 2 ATMs. The member variable freeAtms is a boolean array which is initialized to true in the constructor, indicating both the atm machines are free initially.
• In withdrawMoney(), we first acquire the semaphore, and then check which atm machine is free. This is done through getAvailableATM(). There is a possibility that 2 threads may acquire the semaphore and enter this block of code and modify the shared resource variable freeAtms. So the code to check for available ATMs and mark it as busy is in the synchronized block.
• Once we find the available ATM machine, we withdrawMoney. Once the money is withdrawn, we release the ATM through releaseATM(atmNumber) method. This code is also in synchronized, to ensure that only 1 thread enters this block and modifies freeAtms boolean array. Then we release the semaphore for other waiting threads to acquire and withdrawMoney based on the available ATM machine.

As per the output, at any given point in time, only 2 threads can acquire the semaphore and withdraw money. If a thread is unable to acquire a semaphore, it is blocked until one of the threads which has acquired the semaphore releases it. This is how semaphores can be used to protect more than one copy of a shared resource which in this case is an ATM machine.

My Personal Notes arrow_drop_up