import java.util.Arrays;
import java.util.concurrent.Semaphore;
/**
* {@link <a href=
* "https://[Log in to view URL]"
* target= "_blank">Semaforo : sincronizzazione in accesso, dis-accopiato dalla sincronizzazione alla risorsa</a>}
*
* @author itammb ( Italia Massimiliano Buscati )
* @version JDK 1.15
*
*/
class Main {
private static class ATMQueue {
private Semaphore semaphore; // monitor sugli accessi
private boolean[] freeATMs; // ATM liberi
/**
* @see Semaphore#acquire()
* @see Semaphore#release()
*
*/
public void withDrawMoney() {
try {
semaphore.acquire();
// ATM disponibile
int atmMachine = getAvailable();
// concede esecuzione ad altri thread
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName()
+ " :: correntista -> ha eseguito prelievo moneta sul ATM " + atmMachine);
releaseATM(atmMachine);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
public boolean showtdown() {
synchronized (freeATMs) {
for (int i = 0; i < freeATMs.length; i++)
if (!freeATMs[i])
return false;
}
return true;
}
private int getAvailable() {
int freeAtm = -1; // tutti gli ATM sono occupati
boolean notExit = true;
synchronized (freeATMs) {
for (int i = 0; i < freeATMs.length && notExit; i++)
if (freeATMs[i]) {
freeATMs[i] = notExit = false;
freeAtm = i; // primo ATM trovato libero
}
System.out.println("ATM numero : " + freeAtm + " è disponibile");
return freeAtm;
}
}
private void releaseATM(int numberATM) {
synchronized (freeATMs) {
freeATMs[numberATM] = true;
System.out.println("ATM numero : " + numberATM + " è di nuovo disponibile");
}
}
public ATMQueue(int numberATM) {
semaphore = new Semaphore(numberATM);
// tutti i bancomat sono liberi
freeATMs = new boolean[numberATM];
Arrays.fill(freeATMs, true);
}
}
private static class WithdrawMoneyTask implements Runnable {
private final ATMQueue atmQueue;
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " :: correntista -> in attesa");
// prelieno
atmQueue.withDrawMoney();
}
public WithdrawMoneyTask(ATMQueue atmQueue) {
this.atmQueue = atmQueue;
}
} // WithdrawMoneyTask
private static class UniTest {
public void simulate(int numberATM, int accountHolder) {
ATMQueue atmQueue = new ATMQueue(numberATM); // ATM
// correntisti : thread pool
Thread thread[] = new Thread[accountHolder];
for (int i = 0; i < accountHolder; i++)
thread[i] = new Thread(new WithdrawMoneyTask(atmQueue), "Thread " + i);
for (int i = 0; i < accountHolder; i++)
thread[i].start();
// quando tutti i correntisti hanno svolto le operazioni di cassa automatica, il processo termina
while (atmQueue.showtdown())
;
}
}
public static void main(String args[]) {
// Unit test - simulazione semaforo
new UniTest().simulate(3, 10);
}
}
To embed this project on your website, copy the following code and paste it into your website's HTML: