Я новичок в мониторах и переменных условий. Я использую блокировку и переменные условия на моем мониторе.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);
// ...
}
}
In putdown мы можем самостоятельно [index] .signal, чтобы просыпаться мониторы. Но это не так важно. И в случае сбоя отслеживания наблюдается исключение монитора, когда мы используем wait on condition variable. Зачем? Потому что все они используют 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)
Я обновил код и удалить дополнительный класс, так что все в одном классе, может быть, сейчас это более понятно, где может быть, что ошибка
, пожалуйста, дайте полный стек исключения, это, как правило, хороший первый шаг в отладке – flup
Не смешивайте синхронизацию и 'java.util.concurrent.' Таким образом безумие лежит. – EJP
да, но это все равно работает – Ophelia