我正在编写一个小程序,我需要创建线程(我的代码中的哲学家),这些哲学家需要改变思维,饥饿和饮食之间的状态。 我没有那么远的项目,我有下一个问题:
public class NewMain {
static Philosopher [] p;
public static void main(String[] args) {
p = new Philosopher[5];
p[0] = new Philosopher(0);
p[1] = new Philosopher(1);
p[2] = new Philosopher(2);
p[3] = new Philosopher(3);
p[4] = new Philosopher(4);
for (int i = 0; i<5; i++) {
try{
p[i].run();
if(i == 4) {
p.notifyAll();
}
}
catch(IllegalMonitorStateException e) {}
}
}
}
我正在创造5位哲学家(线程)。其中每个都在其代码中有wait()
条指令:
@Override
public void run() {
int rand;
if (status == 0) {
System.out.println("Philosopher " + id + " is waiting.");
try {
wait();
System.out.println("Awoken");
while(status == 0) {
System.out.println("Philosopher " + id + " is thinking.");
sleep(100);
rand = ThreadLocalRandom.current().nextInt(0,100);
if(rand > 95){
status = 1;
System.out.println("Philosopher " + id + " changed state to hungry.");
}
}
}
catch(InterruptedException e) {
System.out.println("Error!");
}
catch(IllegalMonitorStateException e) {}
}
}
问题是,在调用notifyAll()
时,进程不会唤醒,只是在执行每个线程的run()
方法后才会死掉。
如果有人想知道,我没有使用synchronized
,因为我需要同时运行这些方法。
另外,我试图将notifyAll()
放在线程的run()
方法中。
任何人都可以告诉我发生了什么,为什么线程不会继续 他们的代码?
答案 0 :(得分:4)
notify[All]()
和wait()
应该在同一个实例上使用。您正在通过数组Philosopher[] p
通知,但等待this
Philosopher
。就像 我 等待你,但你正在通知 Sarah 你将会迟到。
已创建主题,但尚未正确启动。调用run
将在当前线程中执行该方法。请改用方法start
。它同时开始执行。
要使用x.notify[All]()
或x.wait()
,您必须位于同步块synchronized(x) { ... }
内。忽略IllegalMonitorStateException
根本无济于事。
...为什么线程不继续使用他们的代码?
在第4个帖子通知后,他们可能会致电wait
。
......过程没有醒来,他们只是死了......
他们不会死,他们还会等待,直到您终止该计划。
我没有使用
synchronized
,因为我需要同时运行这些方法
您需要同时正确运行这些方法,对吧?在这里,至少需要同步以构建wait-notify
通信。
答案 1 :(得分:1)
p
是一个Runnable数组。当你写作
p[i].run();
然后,您正在使用存储在run
位置的对象调用run
方法(实际上您尚未在此处启动一个线程,而不是p[i]
方法)。现在,根据notifyAll
在此对象的监视器 上唤醒所有线程 等待。线程通过调用其中一个等待方法等待对象的监视器。
start()
而不是run()
来启动新主题。notify()
和notifyAll
。