// "Tak pobieznie przegladajac, niepotrzebnie uzywasz kolejki. Zawsze czytaj ID watku na biezaco i najlepiej asynchronicznie."
// Bruno Pitrus
import java.io.Reader;
import java.util.*;
public class Relay implements Runnable {
boolean gotowy, koniec, biega;
Scanner odczyt;
int aktualnyId;
Thread aktualnyThread;
Map<Integer, Thread> mapa;
public Relay(Reader reader) {
gotowy = false;
koniec = false;
biega = false;
aktualnyId = -1;
odczyt = new Scanner(reader);
mapa = new HashMap<>();
}
public void register(int id, Thread competitor) {
mapa.put(id, competitor);
//zglasza do udzialu w sztafecie watek i nadaje mu identyfikator id
}
public void startRelayRace() {
//ustawia zmienna ze bieg sie rozpoczal
gotowy = true;
for (Thread t : mapa.values()) {
synchronized (t) {
t.notify();
//informuje wszystkich zawodnikow ze juz czas
}
}
//rozpoczyna wypuszczanie zawodnikow.
}
public boolean dispatch() {
if (koniec == true) {
return false;
//Reader dostarczyl koniec pliku, sztafeta powinna zostac zakonczona
//(wszyscy zawodnicy wychodza z dispatch z false)
}
if (aktualnyThread == Thread.currentThread()) {
biega = false;
//aktualnyThread watek powrocil
}
while (gotowy == false) {
synchronized (Thread.currentThread()) {
try {
Thread.currentThread().wait();
//bieg sie nie zaczal to kazujemy czekac tym co chca biec
} catch (InterruptedException problem) {
}
}
}
synchronized (this) {
if (aktualnyId == -1 && biega == false) {
//nikt nie biegnie aktualnie
if (!odczyt.hasNextInt()) {
//reader zakonczyl czytanie
koniec = true;
for (Thread t : mapa.values()) {
synchronized (t) {
t.notify();
}
//informuje ze koniec
}
//metoda zwraca false jezeli sztafeta sie zakonczyla
return false;
}
if (aktualnyId == -1) {
aktualnyId = odczyt.nextInt();
//pobranie id kolejnego do biegu
}
synchronized (mapa.get(aktualnyId)) {
mapa.get(aktualnyId).notify();
//poinformuj watek ze jego kolej
}
}
}
while (aktualnyId == -1 || Thread.currentThread() != mapa.get(aktualnyId)) {
synchronized (Thread.currentThread()) {
//zly gosc sie zglasza lub nie chcemy wypuszczac to kazemy czekac
try {
Thread.currentThread().wait();
} catch (InterruptedException problem) {
}
}
if (koniec == true) {
return false;
//bieg sie zakonczyl bo reader nie daje numerkow
}
}
aktualnyId = -1;
//wypuszczamy kolejnego co mial byc w kolejce
aktualnyThread = Thread.currentThread();
biega = true;
//ustawiamy biegacza aktualnego
return biega;
//metoda zwraca true wypuszczajac zawodnika na bieznie
}
public void run() {
}
}