notifyAll() 不唤醒进程
notifyAll() not awakening processes
我正在编写一个 Java 小程序,我需要在其中创建线程(我代码中的哲学家),这些哲学家需要在思考、饥饿和进食之间转换状态。
我对项目的了解还不够深入,我遇到了下一个问题:
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()
方法中。
谁能告诉我发生了什么事以及为什么线程没有继续
用他们的代码?
问题
notify[All]()
和 wait()
应该在同一个实例上使用。您在数组 Philosopher[] p
上进行通知,但在 this
上等待 Philosopher
。就像我在等你,但是你在通知Sarah你要迟到了.
您已创建线程但尚未正确启动它们。调用 run
将在当前线程中执行该方法。请改用 start
方法。它同时开始执行。
要使用 x.notify[All]()
或 x.wait()
,您必须在同步块 synchronized(x) { ... }
中。忽略 IllegalMonitorStateException
根本帮不了你。
答案
... why are the threads not continuing with their code?
他们可能会在 第 4 个线程通知他们之后调用 wait
。
... the processes don't awake and they just die ...
它们不会死,它们仍在等待直到您终止程序。
I'm not using synchronized
because I need to run the methods at the same time
您需要运行同时正确这些方法,对吗?在这里,至少需要同步才能建立 wait-notify
通信。
p
是一个Runnable数组。当你写
p[i].run();
然后,您正在使用存储在 p[i]
位置的对象调用 run
方法(实际上您没有在此处启动线程而是调用 run
方法)。现在,根据 notifyAll
唤醒所有在这个对象的监视器上等待的线程 ]。线程通过调用其中一种等待方法在对象的监视器上等待。
- 您应该使用
start()
而不是 run()
来启动新线程。
notify()
和 notifyAll
用于当线程正在等待获取 当前对象 [=36= 上的监视器时].
我正在编写一个 Java 小程序,我需要在其中创建线程(我代码中的哲学家),这些哲学家需要在思考、饥饿和进食之间转换状态。 我对项目的了解还不够深入,我遇到了下一个问题:
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()
方法中。
谁能告诉我发生了什么事以及为什么线程没有继续 用他们的代码?
问题
notify[All]()
和wait()
应该在同一个实例上使用。您在数组Philosopher[] p
上进行通知,但在this
上等待Philosopher
。就像我在等你,但是你在通知Sarah你要迟到了.您已创建线程但尚未正确启动它们。调用
run
将在当前线程中执行该方法。请改用start
方法。它同时开始执行。要使用
x.notify[All]()
或x.wait()
,您必须在同步块synchronized(x) { ... }
中。忽略IllegalMonitorStateException
根本帮不了你。
答案
... why are the threads not continuing with their code?
他们可能会在 第 4 个线程通知他们之后调用 wait
。
... the processes don't awake and they just die ...
它们不会死,它们仍在等待直到您终止程序。
I'm not using
synchronized
because I need to run the methods at the same time
您需要运行同时正确这些方法,对吗?在这里,至少需要同步才能建立 wait-notify
通信。
p
是一个Runnable数组。当你写
p[i].run();
然后,您正在使用存储在 p[i]
位置的对象调用 run
方法(实际上您没有在此处启动线程而是调用 run
方法)。现在,根据 notifyAll
唤醒所有在这个对象的监视器上等待的线程 ]。线程通过调用其中一种等待方法在对象的监视器上等待。
- 您应该使用
start()
而不是run()
来启动新线程。 notify()
和notifyAll
用于当线程正在等待获取 当前对象 [=36= 上的监视器时].