【发布时间】:2016-04-12 07:35:53
【问题描述】:
我正在使用一个整数变量并与两个线程共享。一个线程应该打印偶数,一个线程应该顺序打印奇数。 但是 notify() 会抛出 IllegalMonitorStateException。
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();
}
}
}
}
输出是:
奇线程 1
Exception in thread "OddThread" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at mywaitnotifytest.Odd.run(App.java:67)
【问题讨论】:
-
这个问题似乎有所不同,因为 OP 在
notify上遇到异常,而不是wait。加上异常的原因是完全不同的,与非synchronized代码无关 -
您没有在锁定的同一对象上调用
notify()。简而言之,不要锁定可变字段。当你改变它时,你改变它。也不要锁定池对象,因为Integer是这样,这会产生令人困惑的后果。 -
我只从同步块调用等待和通知
-
@ortis 当 OP 使用
synchornized时,他/她没有在他们拥有synchronized的对象上调用通知。 -
@NareshMuthyala 使用
synchronized意味着您必须在同一个对象上调用notify/wait。它不会授予您锁定任何对象的权限。
标签: java multithreading wait notify