Ich nehme eine Integer-Variable und Freigabe mit zwei Threads. Ein Thread sollte gerade Zahlen und ein Thread sollte ungerade Zahl nacheinander drucken. Aber notify() werfen IllegalMonitorStateException.java warten und benachrichtigen
package mywaitnotifytest;
public class App {
public static void main(String[] args) {
Integer i=0;
Even even = new Even(i);
even.setName("EvenThread");
Odd odd = new Odd(i);
odd.setName("OddThread");
even.start();
odd.start();
}
}
class Even extends Thread{
Integer var;
Even(Integer var){
this.var=var;
}
@Override
public void run() {
while(true){
synchronized (var) {
if(var%2==0){
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var++;
System.out.println(Thread.currentThread().getName()+" "+var);
var.notify();
}
}
}
}
class Odd extends Thread{
Integer var;
Odd(Integer var){
this.var=var;
}
@Override
public void run() {
while(true){
synchronized (var) {
if(var%2!=0){
try {
var.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
var++;
System.out.println(Thread.currentThread().getName()+" "+var);
var.notify();
}
}
}
}
Und der Ausgang ist:
OddThread 1
Exception in thread "OddThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at mywaitnotifytest.Odd.run(App.java:67)
Diese Frage scheint anders als OP Ausnahme immer auf 'notify', nicht' wait'. Außerdem ist der Grund der Ausnahme ganz anders und als nichts mit nicht 'synchronisiertem' Code zu tun. – ortis
Sie rufen 'notify() 'nicht auf demselben Objekt auf, wie Sie es gesperrt haben. Kurz gesagt, sperren Sie kein veränderbares Feld. Wenn du es mutierst, änderst du es. Sperren Sie auch nicht ein Pool-Objekt, wie 'Integer' ist, da dies verwirrende Konsequenzen haben wird. –
Ich rufe warte und benachrichtige nur vom synchronisierten Block –