为了公开起见,这是与经典的“用餐哲学家”困境有关的作业问题。

现在,当告诉一个线程使用wait()时,将给出一个IllegalMonitorStateException,因为其中一根筷子上已经有一个wait()监视器。

Monitor类被实例化一次,以哲学家的数量作为参数。监视器类如下所示:

public class Monitor
{
        int iPhilosophers = DiningPhilosophers.DEFAULT_NUMBER_OF_PHILOSOPHERS;
        // monitors for chopsticks maybe use condition??
        public final Object[] sticks = new Object[iPhilosophers];

        // Store philosopher states in monitor.
        public enum State {THINKING, HUNGRY, EATING, TALKING};
        public volatile State[] states = new State[iPhilosophers];
        public int[] positions = new int[iPhilosophers];


    public Monitor(int piNumberOfPhilosophers)
    {
        for (int i=0; i<piNumberOfPhilosophers; i++) {
            System.out.println("Philosopher " + (i+1) + " is " + this.states[i]);
            this.sticks[i] = new Object();

        }
    }

    /**
     * Grants request (returns) to eat when both chopsticks/forks are available.
     * Else forces the philosopher to wait()
     */
    public synchronized void pickUp(final int piTID)
    {
        int posn = piTID - 1; // due to piTIDs starting at 1, but stick positions @ 0
        this.states[posn] = State.HUNGRY;
        System.out.println("Hungry Philosopher "+ piTID + " is trying to pickup sticks");

        test(posn);
        System.out.println("Philosopher " + piTID +" is state " + this.states[posn]);
        if (this.states[posn] != State.EATING)
            try {
                System.out.println("Hungry Philosopher "+ piTID + " was told to work on his table manners and wait!");
                this.sticks[posn].wait();
//              synchronized (this.sticks[posn]){
//                  this.sticks[posn].wait();
//              }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
        /**
     * Test the chopsticks on the left and right of the philosopher
     * Give philosopher's position
     */
    public void test(int i){
        System.out.println("Entered test function with posn : " + i);
        System.out.println("left "+this.states[(i+iPhilosophers-1) % iPhilosophers]);
        System.out.println("right "+this.states[(i+1) % iPhilosophers]);
        System.out.println("currently " + this.states[i]);

        // Check if philosophers on left and right are not eating
        if ( (this.states[(i+iPhilosophers-1) % iPhilosophers] != State.EATING) &&
                (this.states[(i+1) % iPhilosophers] != State.EATING) &&
                (this.states[i] == State.HUNGRY) ) {
            // set this state to eating, and signal the chopstick

            this.states[i] = State.EATING;
            System.out.println("Set position " + i + " to " + this.states[i]);
            synchronized (this.sticks[i]) {
                this.sticks[i].notifyAll();
                System.out.println(i + " posn notified all");
            }
        }
    }

    /**
     * When a given philosopher's done eating, they put the chopstiks/forks down
     * and let others know they are available.
     */
    public synchronized void putDown(final int piTID)
    {
            System.out.println("entered putdown");
            int posn = piTID - 1; // due to piTIDs starting at 1
            this.states[posn] = State.THINKING;
            test((posn+iPhilosophers-1) % iPhilosophers);
            test((posn+1) % iPhilosophers);
            System.out.println("Philosopher " + piTID + " is back to " + this.states[posn]);
        }
}

生成的部分输出:
Philosopher 4 is state HUNGRY
Hungry Philosopher 4 was told to work on his table manners and wait!
Hungry Philosopher 2 is trying to pickup sticks
Entered test function with posn : 1
left EATING
right EATING
currently HUNGRY
Philosopher 2 is state HUNGRY
Hungry Philosopher 2 was told to work on his table manners and wait!
Exception in thread "Thread-3" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:503)
    at Monitor.pickUp(Monitor.java:61)
    at Philosopher.run(Philosopher.java:87)
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:503)
    at Monitor.pickUp(Monitor.java:61)
    at Philosopher.run(Philosopher.java:87)

我尝试了几种不同的方法,但是无法弄清楚如果另一个哲学家已经在等待,如何允许任何哲学家使用wait()。我需要使用条件吗?

请注意,这类似于基于同一本O/S书的Dining Philosophers monitor approach in Java: no interleaved thread execution问题,但是并没有帮助我解决此问题。

最佳答案

这边有

        System.out.println("Hungry Philosopher "+ piTID + " was told to work on his table manners and wait!");
        this.sticks[posn].wait();

您需要在synchronized对象上使用this.sticks[posn](即自己的监视器)来调用该对象上的wait()notify方法。

纠正您稍后在代码中使用的方法
synchronized (this.sticks[i]) {
            this.sticks[i].notifyAll();
            System.out.println(i + " posn notified all");
        }

您正在this.sticks[i]和调用notifyAll()上进行同步。用wait()大小写做同样的事情。

关于java - 餐饮哲学家,Java和监视器: IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22515973/

10-09 16:23