关于Boolean类型做为同步锁异常问题

public class Test2 {

private static volatile Boolean aBoolean = true;
static class A implements Runnable{
@Override
public void run() {
synchronized (aBoolean){
while (aBoolean){
try {
System.out.println("进入A, 等待中");
aBoolean.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A over");
}
}
}

static class B implements Runnable{

@Override
public void run() {

try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}

synchronized (aBoolean){
System.out.println("通知A可以运行了");
aBoolean = false;
aBoolean.notifyAll();
//Boolean.TRUE.notifyAll();
}
}
}
public static void main(String[] args) {
new Thread(new A()).start();
new Thread(new B()).start();
}
}

运行结果:

进入A, 等待中
通知A可以运行了
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at Test2$B.run(Test2.java:39)
    at java.lang.Thread.run(Thread.java:748)
由于我们会给aBoolean重新赋值, 导致对象监视器改变, 因为falsetrue这两个常量对应着两个不同的对象。当aBoolean产生变化时,很可能导致不同的线程同步了不同的对象
解决方法: 
将这一行 aBoolean.notifyAll();  改为: Boolean.TRUE.notifyAll();
或者是用显示锁ReentrantLock的方式
posted @ 2018-09-10 15:42  星朝  阅读(575)  评论(0)    收藏  举报