Skip to content

Instantly share code, notes, and snippets.

@Feder1co5oave
Created January 12, 2012 00:47
Show Gist options
  • Save Feder1co5oave/1597760 to your computer and use it in GitHub Desktop.
Save Feder1co5oave/1597760 to your computer and use it in GitHub Desktop.
import java.util.*;
/**
* @author Feder1co 5oave
*/
class Museo {
private class Visita {
final int numero;
int prenotazioni;
int visitatori;
boolean guida;
Visita(int n) { numero = n; }
}
private class ListaVisite extends Vector<Visita> {
private int primaSenzaGuida = 0;
public synchronized Visita getLast() {
if (isEmpty()) return null;
else return get(size() - 1);
}
public synchronized Visita add() {
Visita v = new Visita(size());
add(v);
notify();
return v;
}
public synchronized Visita assegnaGuida() throws InterruptedException {
while (primaSenzaGuida >= size())
wait();
return get(primaSenzaGuida++);
}
}
private final int n;
private ListaVisite visite;
private volatile Visita corrente;
public Museo(int n) {
this.n = n;
visite = new ListaVisite();
corrente = visite.add(); // aggiungo la prima visita
}
public synchronized int prenotaVisita() {
Visita last = visite.getLast();
if (/*visite.getLast() == null || */last.prenotazioni == n)
last = visite.add();
last.prenotazioni++;
return last.numero;
}
public void entraVisitatore(int nVisita) throws InterruptedException {
Visita v = visite.get(nVisita);
synchronized (v) {
while (corrente != v)
v.wait();
v.visitatori++;
System.out.println("Entra visitatore");
if (v.visitatori == v.prenotazioni)
v.notify();
while (!v.guida)
v.wait();
}
}
public synchronized void esceVisitatore() {
synchronized (corrente) {
if (--corrente.visitatori == 0)
corrente.notify();
}
System.out.println("Esce visitatore");
}
public void entraGuida() throws InterruptedException {
Visita v = visite.assegnaGuida();
synchronized (v) {
while (v.visitatori < v.prenotazioni)
v.wait();
v.guida = true;
v.notifyAll();
System.out.println("Inizia visita " + v.numero);
}
}
public void esceGuida() throws InterruptedException {
synchronized (corrente) {
while (corrente.visitatori > 0)
corrente.wait();
}
System.out.println("Termina visita " + corrente.numero);
try {
corrente = visite.get(corrente.numero + 1);
synchronized (corrente) {
corrente.notifyAll();
}
} catch (ArrayIndexOutOfBoundsException ex) {
// non ci sono più visite prenotate
}
}
}
class Visitatore extends Thread {
private Museo m;
private int id;
public Visitatore(Museo m, int id) {
this.m = m;
this.id = id;
start();
}
public void run() {
try {
int nVisita = m.prenotaVisita();
m.entraVisitatore(nVisita);
sleep(1);
m.esceVisitatore();
} catch (InterruptedException e) {
System.out.println("Visitatore " + id + ": " + e.getMessage());
}
}
}
class Guida extends Thread {
private Museo m;
int turni;
public Guida(Museo m, int turni) {
this.m = m;
this.turni = turni;
start();
}
public void run() {
try {
for (int i = 0; i < turni; i++) {
m.entraGuida();
sleep(1);
m.esceGuida();
}
} catch (InterruptedException e) {
System.out.println("Guida: " + e.getMessage());
}
}
}
class Pesa {
public static void main(String args[]) {
Museo m = new Museo(3);
for (int i = 0; i < 12; i++)
new Visitatore(m, i);
for (int i = 0; i < 2; i++)
new Guida(m, 2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment