我正在尝试使用两个不同的线程交替打印奇数和偶数,它们之间使用wait和notify进行协调,并使用锁。
public class OddEvenPrinter {
private Object lock = new Object();
private boolean printFlag = false;
void printOdd() throws InterruptedException {
for(int i=1; i < 25; i=i+2){
synchronized (lock){
while(printFlag){
wait();
}
System.out.println(i + "******** PRINT ODD ");
notifyAll();
}
}
}
void printEven() throws InterruptedException {
for(int i=0; i < 25; i=i+2){
synchronized (lock){
while(!printFlag){
wait();
}
System.out.println(i + "******** PRINT EVEN ");
notifyAll();
}
}
}
我有一个驱动程序来验证这一点。在for循环中不能使用synchronized块吗?我得到了非法监控状态异常。
public static void main(String[] args) throws InterruptedException {
OddEvenPrinter printer = new OddEvenPrinter();
Thread a = new Thread(new Runnable() {
@Override
public void run() {
try {
printer.printEven();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
Thread b = new Thread(new Runnable() {
@Override
public void run() {
try {
printer.printOdd();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
a.start();
b.start();
System.out.println("All DONE.....");
}
问题:
您正在同步lock
对象,但调用wait()
,这相当于this.wait()
。
注意this
表示的对象与lock
持有的对象不同,并且每个对象都有自己单独的监视器。
你的每个线程在某个时刻获得lock
的监视器,但随后通过this.wait()
试图释放this
的监视器。因为它从来没有获得过监视器IllegalMonitorStateException
,所以被抛出。
解决方案:
使用lock.wait()
和lock.notifyAll()
,因为你的线程正在lock
上同步。