package ar.com.javacuriosities.concurrency.semaphore;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/*
* La clase Semaphore permite definir un numero acotado de permits para el acceso a un recurso compartido.
* Debemos indicarle al constructor cuantos permits (tickets) podrán ser usados al mismo tiempo.
*
* Semaphore(10) = Crea diez tickets disponibles
*/
public class Main {
public static void main(String args[]) {
// Creamos un semáforo con 10 tickets
Semaphore semaphore = new Semaphore(10);
// Creamos un set de Threads que son ejecutados
for (int i = 1; i <= 5; i++) {
new Reader("Reader-" + i, semaphore).start();
}
for (int i = 1; i < 4; i++) {
new Writer("Writer-" + i, semaphore).start();
}
for (int i = 6; i <= 10; i++) {
new Reader("Reader-" + i, semaphore).start();
}
}
/*
* Clase que representa un Escritor el cual necesita la exclusividad sobre
* el recurso para escribir
*/
private static final class Writer extends Thread {
private Semaphore semaphore;
public Writer(String name, Semaphore semaphore) {
super(name);
this.semaphore = semaphore;
}
@Override
public void run() {
try {
System.out.println(getName() + ": Trying to write");
/*
* Solicita 10 tickets, si no los hay se queda esperando El
* Escritor espera de que no haya nadie leyendo para escribir
*/
semaphore.acquire(10);
System.out.println(getName() + ": wrote something");
// Dormimos un tiempo al azar
TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 50));
// Liberamos 10 tickets
semaphore.release(10);
} catch (InterruptedException e) {
// Log and Handle exception
e.printStackTrace();
}
}
}
/*
* Representa un Lector el cual solo necesita 1 ticket para leer del recurso
*/
private static final class Reader extends Thread {
private Semaphore semaphore;
public Reader(String name, Semaphore semaphore) {
super(name);
this.semaphore = semaphore;
}
@Override
public void run() {
try {
System.out.println(getName() + ": Trying to read");
// Solicitamos un ticket
semaphore.acquire();
System.out.println(getName() + ": Read something");
// Dormimos un tiempo al azar
TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 50));
// Liberamos un ticket
semaphore.release();
} catch (InterruptedException e) {
// Log and Handle exception
e.printStackTrace();
}
}
}
}