用餐哲学家Monitor类中的java.lang.IllegalMonitorStateException



我是监控器和条件变量的新手。我在监视器中使用锁定和条件变量。

public class Monitor  
{   
    private final int piNumberOfPhilosophers;
    private PhilosopherCard[] self;
    private Integer[] names;
    private int invited = 0;
    static Lock lock = new ReentrantLock();
    private Condition[] status; // = lock.newCondition();
    private String[] state;
    /**
     * Constructor
     */
    public Monitor(int piNumberOfPhilosophers)
    {        this.piNumberOfPhilosophers = piNumberOfPhilosophers;         
        self = new PhilosopherCard[this.piNumberOfPhilosophers];
        names = new Integer[this.piNumberOfPhilosophers];
        status = new Condition [this.piNumberOfPhilosophers];
        state = new String [this.piNumberOfPhilosophers];
        //Arrays.asList(state).indexOf(4);      
        }
    public void invitePhilosopher (int id){
        names[invited] = id;
        System.out.println(invited);
        PhilosopherCard philosopher = new PhilosopherCard("thinking");
        self[invited] = philosopher;
        status[invited] =lock.newCondition();
        state[invited] = "thinking";
        invited++;
        }           
    /**
     * check other philosophers (<_<) - > (0_o) -> (>_>)
     */
    private void  test (int index){
        lock.lock();
        int left = index-1;
        int right = index +1;
        if(index==0){
            left=piNumberOfPhilosophers-1;
        }
        if(index == piNumberOfPhilosophers-1){
            right = 0;
        }
        if((state[left]!="eating")&(state[right]!="eating")){
            state[index]="eating";
            status[index].signal();
            }
        lock.unlock();
    }

    public void pickUp(final int piTID) throws InterruptedException
    {        
        int index = Arrays.asList(names).indexOf(piTID);    
        state[index]="hungry";
        test(index);
        if(!state[index].equals("eating")){     
                status[index].wait();
        }   
    }
    /**
     * When a given philosopher's done eating, they put the chopstiks/forks down
     * and let others know they are available.
     */
    public void putDown(final int piTID)
    {   
        int index = Arrays.asList(names).indexOf(piTID);
        self[index].setState("thinking");
        int left = index-1;
        int right = index +1;
        if(index==0){
            left=piNumberOfPhilosophers-1;
        }
        if(index == piNumberOfPhilosophers-1){
            right = 0;
        }
        test(left);
        test(right);
        // ...
    }

}

在镇压中,我们可以自我[索引]。信号唤醒监视器。但这并没有那么重要。并且,在拾取方法中,当我们使用等待条件变量时,监控器会发生异常。为什么?因为他们都用一把锁?所有跟踪

Exception in thread "Thread-1" Exception in thread "Thread-3" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at Monitor.pickUp(Monitor.java:75)
    at Philosopher.run(Philosopher.java:95)
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at Monitor.pickUp(Monitor.java:75)
    at Philosopher.run(Philosopher.java:95)

我更新了代码并删除了额外的类,所以所有这些都在一个类中,也许现在更清楚了

p>你做错了很多事情。
  1. 您在this上是synchronizing,而在PhilosopherCard.lock上未锁定。所谓锁定,我指的是PhilosopherCard.lock.lock();
  2. 您使用的是wait而不是await

更新更多信息

如果你看一下你的这段代码并删除synchronized,代码就不会失败。

   private void test (int index){
        PhilosopherCard.lock.lock();
        int left = index-1;
        int right = index +1;
        if(index==0){
            left=piNumberOfPhilosophers-1;
        }
        if(index == piNumberOfPhilosophers-1){
            right = 0;
        }
        if((state[left]!="eating")&(state[right]!="eating")){
            state[index]="eating";
            status[index].signal();;
            }
        PhilosopherCard.lock.unlock();
    }

signal中,它类似于await,但如果没有同步,为什么它不会抛出IMSE?那是因为你拿着PhilosopherCard.lock锁定。如果你去掉了那两把锁,你就会得到IMSE。

您在pickUp中遇到了该问题。我会将synchronized一起从方法中删除。为什么?因为您正在混合同步。如果您想使用synchronized进行同步,那没关系,但如果您使用java.util.concurrent.Lock进行同步,则不能使用synchronized

synchronized关键字可以让您在对象上使用waitnotifynotifyAll

j.u.c.Lockj.u.c.Condition允许您使用awaitsignalsignalAll。所以我的建议是要么只使用Lock/Condition,要么使用synchronized。不是两者都有。

相关内容

  • 没有找到相关文章

最新更新