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() 方法中。

谁能告诉我发生了什么事以及为什么线程没有继续 用他们的代码?

问题

  1. notify[All]()wait() 应该在同一个实例上使用。您在数组 Philosopher[] p 上进行通知,但在 this 上等待 Philosopher。就像在等,但是在通知Sarah你要迟到了.

  2. 已创建线程但尚未正确启动它们。调用 run 将在当前线程中执行该方法。请改用 start 方法。它同时开始执行。

  3. 要使用 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 synchronizedbecause I need to run the methods at the same time

您需要运行同时正确这些方法,对吗?在这里,至少需要同步才能建立 wait-notify 通信。

p是一个Runnable数组。当你写

p[i].run();

然后,您正在使用存储在 p[i] 位置的对象调用 run 方法(实际上您没有在此处启动线程而是调用 run 方法)。现在,根据 notifyAll

唤醒所有在这个对象的监视器等待的线程 ]。线程通过调用其中一种等待方法在对象的监视器上等待。

  1. 您应该使用 start() 而不是 run() 来启动新线程。
  2. notify()notifyAll 用于当线程正在等待获取 当前对象 [=36= 上的监视器时].