// "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 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() { } }