import
java.io.*;
import
java.util.Arrays;
import
java.util.concurrent.Semaphore;
class
ATMQueue {
private
Semaphore semaphore;
private
boolean
[] freeAtms;
public
ATMQueue()
{
semaphore =
new
Semaphore(
2
);
freeAtms =
new
boolean
[
2
];
Arrays.fill(freeAtms,
true
);
}
public
void
withDrawMoney()
{
try
{
semaphore.acquire();
int
atmMachine = getAvailableATM();
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
(InterruptedException e) {
e.printStackTrace();
}
}
private
void
releaseATM(
int
atmNumber)
{
synchronized
(freeAtms)
{
freeAtms[atmNumber] =
true
;
}
}
private
int
getAvailableATM()
{
int
freeAtm = -
1
;
synchronized
(freeAtms)
{
for
(
int
i =
0
; i < freeAtms.length; i++) {
if
(freeAtms[i]) {
freeAtms[i] =
false
;
freeAtm = i;
break
;
}
}
}
return
freeAtm;
}
}
class
WithdrawMoneyTask
implements
Runnable {
private
ATMQueue atmQueue;
public
WithdrawMoneyTask(ATMQueue atmQueue)
{
this
.atmQueue = atmQueue;
}
@Override
public
void
run()
{
System.out.println(
Thread.currentThread().getName()
+
": - about to withdraw money after acquiring the permit"
);
atmQueue.withDrawMoney();
}
}
class
GFG {
public
static
void
main(String[] args)
{
System.out.println(
"GFG!"
);
ATMQueue atmQueue =
new
ATMQueue();
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();
}
}
}