为了公开起见,这是与经典的“用餐哲学家”困境有关的作业问题。
现在,当告诉一个线程使用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/