我曾多次见到Java中使用对象监视器,但我认为任何对象监视器逻辑都可以轻松地通过使用同步代码块和/或方法来替代。使用显式对象监视器的目的是什么,而不仅仅是仔细协调同步代码块以及原子基元?
始终存在一个监视器对象。当您使用同步块时,您的类实例是监视器对象。
因此,使用显式对象的原因:
1)您可以在类实例之间共享它们,以同步访问共享资源
2)更加明确
3)您可以为监视器对象指定有用的名称
4)更加灵活
您在区分不存在的事情(或者使用不常见的术语)。在Java术语中,监视器是用作synchronized块参数的对象(或者,在同步实例方法的情况下,隐式地使用this
实例,并且在同步静态方法中使用类实例)。
synchronized
块使用封闭对象作为其监视器,换句话说,它相当于使用synchronized(this) { }
。问题是作用域/可见性:任何外部类都可以选择在相同实例上进行同步并干扰您的同步逻辑。通过使用private final
引用作为监视器,这就不再可能(假设没有反射猫腻)。使用私有锁对象而不是对象的内在锁定(或任何其他公共可访问锁)具有优点。将锁对象设置为私有封装了锁,使客户端代码无法获取它,而公共可访问锁允许客户端代码参与其同步策略 - 正确或不正确。错误地获取另一个对象的锁的客户端可能会引起活力问题,验证公共可访问锁是否正确使用需要检查整个程序而不是单个类。