В моем основном потоке я создаю и запускаю четыре потока (A,B,C,D
), которые печатают буквы и цифры на консоли каждые 500–1000 мс. Например A1,A2,A3
и т.д.
Предполагается, что основной поток приостанавливает случайный Letter
поток каждые 100 мс, а затем пробуждает его. Через 2 секунды предполагается убить их всех.
Моя проблема в том, что я не могу приостановить случайный поток Letter
, а затем разбудить его, потому что я получаю: IllegalMonitorStateException
Мой класс основного потока:
public class Main extends Thread {
private boolean alive;
private ArrayList<Letter> letters;
private Letter toStop;
public static Object mutex;
public Main() {
letters = new ArrayList<Letter>();
alive = true;
mutex = new Object();
}
public void run() {
try {
Timer timer = new Timer();
timer.schedule(new StopTask(timer, this), 2 * 1000);
letters.add(new Letter());
letters.add(new Letter());
letters.add(new Letter());
letters.add(new Letter());
for (Letter letter : letters) {
new Thread(letter).start();
}
while (alive) {
synchronized (mutex) {
toStop = letters.get((int) (Math.random() * letters.size()));
System.out.println(toStop.getLetter() + " spi");
mutex.wait();
Thread.sleep(100);
mutex.notify();
}
for (Letter letter : letters) {
letter.kill();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void kill() {
alive = false;
}
}
и мой класс Letter
:
class Letter implements Runnable {
private static int ID;
private char letter;
private int counter;
private boolean alive;
public Letter() {
letter = (char) ('A' + ID);
alive = true;
ID++;
}
@Override
public void run() {
try {
while (alive) {
System.out.println(letter + "" + counter);
counter++;
Thread.sleep((int) (Math.random() * 501 + 500));
}
System.out.println("Watek " + letter + " sie zakonczyl");
} catch (Exception e) {
}
}
public void kill() {
alive = false;
}
public char getLetter() {
return letter;
}
}
StopTask
:
import java.util.Timer;
import java.util.TimerTask;
public class StopTask extends TimerTask {
private Timer timer;
private Main main;
public StopTask(Timer timer, Main main) {
this.timer = timer;
this.main = main;
}
public void run() {
System.out.println("Time's up!");
main.kill();
timer.cancel(); //Not necessary because we call System.exit
}
}