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重新赋值, 导致对象监视器改变, 因为false和true这两个常量对应着两个不同的对象。当aBoolean产生变化时,很可能导致不同的线程同步了不同的对象解决方法: 将这一行 aBoolean.notifyAll(); 改为: Boolean.TRUE.notifyAll();或者是用显示锁ReentrantLock的方式