为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里?
wait(), notify()和notifyAll()方法由同步监视器对象来调用:
对synchronized修饰的同步方法, 因为默认的实例(this)是同步监视器本身, 所以可以直接使用这三个方法.
对synchronized修饰的同步代码块,同步监视器是synchronized括号后的对象,所以必须使用该对象调用者三个方法。
Java中,任何对象都可以作为锁,并且 wait(),notify()等方法用于等待对象的锁或者唤醒线程,在 Java 的线程中并没有可供任何对象使用的锁,所以任意对象调用方法一定定义在Object类中。
wait(), notify()和 notifyAll()这些方法在同步代码块中调用
有的人会说,既然是线程放弃对象锁,那也可以把wait()定义在Thread类里面啊,新定义的线程继承于Thread类,也不需要重新定义wait()方法的实现。然而,这样做有一个非常大的问题,一个线程完全可以持有很多锁,你一个线程放弃锁的时候,到底要放弃哪个锁?当然了,这种设计并不是不能实现,只是管理起来更加复杂。
综上所述,wait()、notify()和notifyAll()方法要定义在Object类中。
收起当一个线程进入wait之后,就必须等其他线程notify/notifyall,使用notifyall,可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。
如果没把握,建议notifyAll,防止notigy因为信号丢失而造成程序异常。
notify() 方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。
而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。
收起