为何以下代码会抛出IllegalMonitorStateException异常?
为什么这段代码会抛出IllegalMonitorStateException?
先贴出问题代码:
synchronized (lock) { //lock.notifyAll(); new Thread(() -> { System.out.println("同步代码块中创建线程..."); try { lock.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } }).start(); }
核心原因
Java 中调用 Object.wait()(包括配套的 notify()/notifyAll())有严格规则:调用线程必须持有该对象的监视器锁(monitor lock)。直白点说,你得先通过synchronized(lock)代码块或者synchronized方法拿到lock对象的锁,才能在这个锁上调用wait()系列方法。
代码问题拆解
这段代码里,主线程确实进入了synchronized(lock)块,拿到了lock的锁,但它只是在这个块里创建并启动了一个新线程。新线程是完全独立的执行流,它并没有进入任何synchronized(lock)的代码块或方法——也就是说,新线程根本没持有lock对象的监视器锁。
当新线程执行到lock.wait()时,因为它没满足「持有锁」的前提条件,直接触发IllegalMonitorStateException异常。
修复示例
如果要让新线程安全调用lock.wait(),得让它自己先获取lock的锁,比如把wait()放到synchronized(lock)块内:
synchronized (lock) { new Thread(() -> { System.out.println("同步代码块中创建线程..."); synchronized (lock) { // 新线程自行获取lock的锁 try { lock.wait(); } catch (InterruptedException e) { throw new RuntimeException(e); } } }).start(); }
内容的提问来源于stack exchange,提问作者XrazYang
相关产品推荐
相关产品推荐

