任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式,这种实现主要体现在在虚拟机层面(对象头)和字节码(monitoreter monitorexit和synchronized方法修饰符)层面的支持 。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,这种实现主要通过一些数据结构和算法使用java代码实现。这两者之间有些差别如下:
对比项 | Object Monitor | Condition |
前置条件 | 获取对象的锁 | 先获取到显示锁,再根据显式锁获取条件Condition对象。Lock.lock();Lock.newCondition() |
调用方式 | 调用对象的wait方法,obj.wait() | 调用Condition对象的awaitXX()方法 |
等待条件个数 | 一个 | 多个 |
当线程释放锁并进入等待条件 | 支持 | 支持 |
当前线程释放锁并进入等待状态,在等待状态中不响应中断 | 不支持 | 支持 |
当前线程释放锁并进入超时等待状态 | 支持 | 支持 |
当前线程释放锁并进入等待状态到将来的某个时间 | 不支持 | 支持 |
唤醒等待队列中的一个线程 | 支持 | 支持 |
唤醒等待队列中的所在线程 | 支持 | 支持 |
Java对象自带监视器与Condition接口的监视器的对比
从以上对比表可以看出它们再者之间的最大不同就是一个支持多个等待队列、另一个却不支持,在复杂的并发编程中Codition明显有更大的优势与便利。