wait 和 notify 这个为什么要在 synchronized 代码块中

wait 和 notify 用来实现多线程之间的协调,wait 表示让线程进入到阻塞状态, notify 表示让阻塞的线程唤醒。

wait 和 notify 必然是成对出现的,如果一个线程被 wait()方法阻塞,那么必然需 要另外一个线程通过 notify()方法来唤醒这个被阻塞的线程,从而实现多线程之 间的通信。
在多线程里面,要实现多个线程之间的通信,除了管道流以外,只能通过共享变 量的方法来实现,也就是线程 t1 修改共享变量 s,线程 t2 获取修改后的共享变 量 s,从而完成数据通信。

但是多线程本身具有并行执行的特性,也就是在同一时刻,多个线程可以同时执 行。在这种情况下,线程 t2 在访问共享变量 s 之前,必须要知道线程 t1 已经修 改过了共享变量 s,否则就需要等待。

同时,线程 t1 修改过了共享变量 S 之后,还需要通知在等待中的线程 t2。

所以要在这种特性下要去实现线程之间的通信,就必须要有一个竞争条件控制线 程在什么条件下等待,什么条件下唤醒。

而 Synchronized 同步关键字就可以实现这样一个互斥条件,也就是在通过共享 变量来实现多个线程通信的场景里面,参与通信的线程必须要竞争到这个共享变 量的锁资源,才有资格对共享变量做修改,修改完成后就释放锁,那么其他的线 程就可以再次来竞争同一个共享变量的锁来获取修改后的数据,从而完成线程之 前的通信。
所以这也是为什么 wait/notify 需要放在 Synchronized 同步代码块中的原因,有 了 Synchronized 同步锁,就可以实现对多个通信线程之间的互斥,实现条件等 待和条件唤醒。

另外,为了避免 wait/notify 的错误使用,jdk 强制要求把 wait/notify 写在同步代 码块里面,否则会抛出 IllegalMonitorStateException

最后,基于 wait/notify 的特性,非常适合实现生产者消费者的模型,比如说用 wait/notify 来实现连接池就绪前的等待与就绪后的唤醒。

你可能感兴趣的:(java,jvm,开发语言)