0

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

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);

        // ...
    }


}

在 putdown 中,我们可以使用 self[index].signal 来唤醒监视器。但这并不重要。并且,当我们在条件变量上使用等待时,在拾取方法中发生监视器异常。为什么?因为他们都使用1把锁?所有痕迹

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)

我更新了代码并删除了额外的类,所以都在一个类中,也许现在更清楚那个错误可能在哪里

4

1 回答 1

2

你做错了很多事情。

  1. synchronizingthis而不是锁定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关键字可以允许您在对象上使用wait,notifynotifyAll

和允许您使用j.u.c.Lock, , . 所以我的建议是仅使用/或. 不是都。j.u.c.ConditionawaitsignalsignalAllLockConditionsynchronized

于 2015-04-08T23:16:15.323 回答