gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 04:47:40 24 4
gpt4 key购买 nike

我对监视器和条件变量不熟悉。我在监视器中使用锁定和条件变量。

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)

我更新了代码并删除了额外的类,因此所有内容都在一个类中,也许现在更清楚该错误在哪里

最佳答案

您做错了很多事情。

  1. 您正在同步,而不是锁定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类似,但是没有synchronized为什么它不会抛出IMSE?那是因为你拿着PhilosopherCard.lock 锁定。如果你取下这两把锁,你就会得到 IMSE。

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

synchronized 关键字允许您在对象上使用 waitnotifynotifyAll

j.u.c.Lockj.u.c.Condition 允许您使用 awaitsignalsignalAll。所以我的建议是仅使用 Lock/Conditionsynchronized。两者都不是。

关于就餐哲学家的Monitor类中的java.lang.IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29526906/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com