【发布时间】:2015-07-28 21:40:01
【问题描述】:
在我的主线程中,我创建并启动了四个线程 (A,B,C,D),它们每 500 到 1000 毫秒在控制台上打印字母和数字。
比如A1,A2,A3等
主线程假设每 100 毫秒随机暂停一次Letter 线程,然后将其唤醒。 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
}
}
【问题讨论】:
-
您在
mutex上进行同步,并在toStop上调用wait()。你应该打电话给mutex.wait() -
@NitinDandriyal 但我想暂停
toStop,直到我调用通知。 -
@NitinDandriyal 我更新了
run中的Main线程永无止境。我添加了StopTask,所以现在复制的代码将编译并运行。 -
您必须首先了解,要对任何对象调用等待和通知,您必须首先使用
synchronized关键字获取该对象的监视器,否则您将得到此异常。请牢记这一点,重新编写代码。 -
目前你的
mutex只对主线程可见,其余的Letter线程不知道也不关心它,因此没有意义等待并通知当前代码的主线程
标签: java multithreading wait notify