0

我正在编写一个小的 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()

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

4

2 回答 2

4

问题

  1. notify[All]()并且wait()应该在同一个实例上使用。您正在阵列上通知Philosopher[] p,但在等待this哪个是Philosopher. 就像在等,但通知莎拉你要迟到了

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

  3. 要使用x.notify[All]()or x.wait(),您必须在同步块内synchronized(x) { ... }。忽略IllegalMonitorStateException对你没有任何帮助。

答案

...为什么线程不继续他们的代码?

他们可能会wait 第 4 个线程通知他们之后调用。

......进程不会醒来,他们只是死去......

他们不会死,他们仍然会等到您终止程序。

我没有使用synchronized,因为我需要同时运行这些方法

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

于 2018-02-06T17:56:09.600 回答
1

p是一个可运行的数组。当你写

p[i].run();

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

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

  1. 你应该用它start()run()启动一个新线程。
  2. notify()并且notifyAll在线程等待获取当前对象上的监视器时使用。
于 2018-02-06T17:59:35.863 回答