Created
July 25, 2011 22:26
-
-
Save mattmils/1105404 to your computer and use it in GitHub Desktop.
Rematori
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Matteo Rolla | |
// matr. 730928 | |
import java.util.ArrayList; | |
import java.util.List; | |
public class Rolla730928 { | |
public static final int NUM = 2; | |
public static final int NUM_REMATE = 3; | |
private static final int IDLE = 0; | |
private static final int READY = 1; | |
private static final int END = 2; | |
private static final int CENA = 3; | |
private static void log(String text) { | |
System.out.println(Thread.currentThread().getName() + "> " + text); | |
} | |
public class Rematore implements Runnable { | |
private final Allenatore _allenatore; | |
public Rematore(Allenatore allenatore) { | |
_allenatore = allenatore; | |
} | |
@Override | |
public void run() { | |
while (true) { | |
// Aggiungiamo un po' di delay. | |
long time = (long) (Math.random() * 5000); | |
try { | |
Thread.sleep(time); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
_allenatore.arrivaAlCampo(this); | |
_allenatore.iniziaAllenamento(); | |
for (int i = 1; i <= NUM_REMATE; i++) { | |
_allenatore.rema(i); | |
} | |
if(_allenatore.concludiAllenamento()) { | |
log("Sono stato il migliore!"); | |
} | |
_allenatore.cena(); | |
_allenatore.concludiGiornata(this); | |
} | |
} | |
} | |
public class Allenatore { | |
private final List<Rematore> _list; | |
private int _start = 0; | |
private int _sync = 0; | |
private int _turno = 1; | |
private int _state = IDLE; | |
private boolean _migliore = false; | |
public Allenatore() { | |
_list = new ArrayList<Rematore>(); | |
} | |
public synchronized void arrivaAlCampo(Rematore rematore) { | |
while (_state != IDLE || _list.size() == NUM) { | |
try { | |
log("Tutto pieno per l'allenamento. Devo aspettare."); | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Presentato all'allenamento."); | |
_list.add(rematore); | |
// Okay enough players. | |
if (_list.size() == NUM) { | |
_state = READY; | |
} | |
notifyAll(); | |
} | |
public synchronized void iniziaAllenamento() { | |
while (_state != READY) { | |
try { | |
log("Attende di iniziare l'allenamento."); | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Allenamento iniziato."); | |
_start++; | |
notifyAll(); | |
} | |
public synchronized void rema(int turno) { | |
while (_turno != turno || _start != NUM) { | |
try { | |
log("Aspetta il suo turno di voga."); | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Ha remato nel turno numero " + _turno + "."); | |
_sync++; | |
if (_sync == _list.size()) { | |
// Ultimo turno cambia stato. | |
if (_turno == NUM_REMATE) { | |
_state = END; | |
} | |
else | |
_turno++; | |
_sync = 0; | |
} | |
notifyAll(); | |
} | |
public synchronized boolean concludiAllenamento() { | |
while (_state != END) { | |
try { | |
log("Attende che tutti i rematori finiscano di remare."); | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Ha finito di allenarsi."); | |
_start--; | |
if(_start == 0) { | |
_state = CENA; | |
} | |
notifyAll(); | |
return logicaMigliore(); | |
} | |
public synchronized void cena() | |
{ | |
while (_state != CENA) { | |
try { | |
log("Attende di iniziare la cena."); | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Ha cenato."); | |
_start++; | |
notifyAll(); | |
} | |
public synchronized void concludiGiornata(Rematore rematore) | |
{ | |
while (_state != CENA || _start != NUM) { | |
try { | |
wait(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
log("Ha concluso la sua giornata!"); | |
_list.remove(rematore); | |
// La lista è vuota, tutti i rematori se ne sono andati. | |
if (_list.isEmpty()) | |
reset(); | |
notifyAll(); | |
} | |
private boolean logicaMigliore() { | |
// Il migliore è già stato scelto. | |
if(_migliore) | |
return false; | |
// Il migliore non è stato scelto e siamo all'ultimo rematore. | |
if(_start == 0 && !_migliore) | |
return true; | |
// Decisione non deterministica. | |
return _migliore = (Math.random() > 0.5); | |
} | |
private void reset() { | |
// RESETTING. | |
_start = 0; | |
_sync = 0; | |
_turno = 1; | |
_state = IDLE; | |
_migliore = false; | |
} | |
} | |
public Rolla730928() { | |
Allenatore allenatore = new Allenatore(); | |
for (int i = 0; i < NUM; i++) { | |
Thread thread = new Thread(new Rematore(allenatore)); | |
thread.setName("Rematore " + i); | |
thread.start(); | |
} | |
} | |
public static void main(String[] args) { | |
new Rolla730928(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment