Wątki - prośba o zweryfikowanie rozwiązania

0

Witam. Poniżej załączam treść zadania oraz proponowane przeze mnie rozwiązanie. Troszkę mi się wydaje, że można to zrobić lepiej. Ogólnie troche je zmodyfikowałem i powinno sprawdzac czy ktorys ze spiewakow skonczyl juz swoje biadolenie i przerwac wszystko, a pozniej porownac ktory wiecej wyspiewal w tym czasie (bo maja rozne repertuary)

Zadanie 1 (3p)
Zmodyfikować zadanie 3 z tematu 6 tworząc program symulujący konkurs śpiewania.

Śpiewacy są obiektami klasy Spiewak (wątek).
Juror jest obiektem klasy Juror (wątek). Głównym zadaniem jurora jest zmierzyć czas trwania konkursu, czas jest podany w momencia tworzenia obiektu.

Przy tworzeniu obiektu - śpiewaka określony jest jego "repertuar" typu String (metoda spiewaj()). Konkursowe wykonanie śpiewaka polega na cyklicznym wydrukowywaniu na konsoli kolejnego (od pierwszego do ostatniego, potem powrót do pierwszego ...) znaku repertuaru. Między kolejnymi "wyśpiewanymi" znakami należy zastosować opóźnienia czasowe (losowe) do 2 sekund.

Wygrywa śpiewak, któremu po upływie określonego czasu udało się "wyśpiewać" większą liczbę znaków ze swojego repertuaru.
W trakcie działania, program powinien wyprowadzać na zewnątrz jak najwięcej informacji, aby można było śledzić przebieg konkursu.

Stworzyć w/w klasy w taki sposób, aby następujący program:

public class Konkurs {
        
    public static void main(String[] args)
    {
            // tworzenie obiektów - śpiewaków z podanymi "repertuarami"
        Spiewak tenor = new Spiewak("Tenor") { ... return "doremifasolasido"; ... };                         
        Spiewak soprano = new Spiewak("Soprano") { ... return "obladioblada"; ... };                        
        
        Juror juror = new Juror(30);        // tworzenie obiektu - jurora z podanym czasem trwania konkursu (30 sekund)
                                                            
        juror.start();        // wywołanie metody start() z klasy java.lang.Thread: juror startuje swój wątek, mierzy czas    
        
            // śpiewacy startują swoje wątki: zaczynają "śpiewać"
        tenor.start();    
        soprano.start();
        
        try {
            juror.join();                   // wywołanie metody join() z klasy java.lang.Thread: czekanie aż wątek jurora zakończy swoją pracę
        } catch (InterruptedException e) { e.printStackTrace(); }
        finally{
                // wywołanie metody interrupt() z klasy java.lang.Thread: przerwanie działania wątków - śpiewaków
            tenor.interrupt();                
            soprano.interrupt();
        }
        
        // prezentacja wyniku konkursu
        // ...
    }
}

wyprowadził na konsolę wyniki podobne do tych poniżej:

Czas 1:
Soprano: o
Tenor: d
Tenor: o
Soprano: b
Czas 2:
Tenor: r
Czas 3:
Soprano: l
Tenor: e
Tenor: m
...
Czas 30:
Soprano: d
Soprano: a

Tenor wygrał!

public class Juror extends Thread {

	private int timeInSeconds;

	public Juror(int timeInSeconds) {
		super("Juror");
		this.timeInSeconds = timeInSeconds;
	}

	@Override
	public void run() {
		try {
			for (int i = 1; i <= timeInSeconds; i++) {
				System.out.println("Czas " + i + ":");

				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			System.out.println("Stop");
		}

	}
}

import java.util.Random;

public abstract class Spiewak extends Thread {

	private int frequency;

	public int soundsMade;

	public Spiewak(String name) {
		super("Singer" + name);

		Random rand = new Random();
		this.frequency = (rand.nextInt(20 - 1 + 1) + 1) * 20;
	}

	public abstract String sing();

	@Override
	public void run() {
		char[] sounds = sing().toCharArray();

		try {
			for (int i = 0; i < sounds.length; i++) {
				System.out.println(this.getName() + ": " + sounds[i]);
				soundsMade++;

				sleep(frequency);
			}
		} catch (InterruptedException e) {
			System.out.println("Hey! I am not done yet! :(");
		}

	}
}


public class App {

	public static void main(String[] args) {

		Spiewak tenor = new Spiewak("Tenor") {
			public String sing() {
				return "doremifasolasido";
			}
		};
		Spiewak soprano = new Spiewak("Soprano") {
			public String sing() {
				return "obladioblada";
			}
		};

		Juror juror = new Juror(30);

		juror.start();

		tenor.start();
		soprano.start();

		while (juror.isAlive()) {
			if (!tenor.isAlive()) {
				soprano.interrupt();
				juror.interrupt();
				break;
			} else if (!soprano.isAlive()) {
				tenor.interrupt();
				juror.interrupt();
				break;
			}
		}
		
		if(juror.isAlive())
			juror.interrupt();

		if (tenor.soundsMade > soprano.soundsMade) {
			System.out.println("Tenor wygrał!");
		} else if (tenor.soundsMade > soprano.soundsMade) {
			System.out.println("Soprano wygrał!");
		} else {
			System.out.println("Niewiarygodne! Mamy remis!");
		}

	}
}

Wychodzi na to, że działa, ale konsola pokazuje mi np coś takiego:

Czas 1:
SingerSoprano: o
SingerTenor: d
SingerTenor: o
SingerSoprano: b
SingerTenor: r
SingerTenor: e
SingerSoprano: l
SingerTenor: m
Czas 2:
SingerSoprano: a
SingerTenor: i
SingerTenor: f
SingerSoprano: d
SingerTenor: a
SingerTenor: s
SingerSoprano: i
SingerTenor: o
Czas 3:
SingerSoprano: o
SingerTenor: l
SingerTenor: a
SingerSoprano: b
SingerTenor: s
SingerTenor: i
SingerSoprano: l
Czas 4:
SingerTenor: d
SingerSoprano: a
SingerTenor: o
Tenor wygrał!
Stop
Hey! I am not done yet! :(

Tzn. najpierw wynik, a później skargę spiewaka, który jeszcze nie skończył. Miałem też output gdzie Tenor np. skończył, ale Sopran jeszcze dodał swoje 5 gr. Nie rozumiem za bardzo dlaczego.

0

Twój main w while im przeywa, więc co się dziwisz :P? Catch w śpiewaku łapie wyjatek i wyswietla Ci wiadomość - przeywasz mu kiedy jest w sleepie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1