我已经多次看到java中使用过的对象监视器,但在我看来,任何对象监视器逻辑都可以通过使用同步代码块和/或方法轻松替换。
使用显式对象监视器的目的是什么,而不是仅仅仔细协调同步代码块和Atomic原语?
答案 0 :(得分:4)
总有一个监视器对象。当您具有同步块时,您的类实例是监视器对象。 所以使用显式对象的理由:
1)您可以在类实例之间共享它们以同步对共享资源的访问
2)更明确
3)您可以为监视器对象提供有用的名称
4)更灵活
答案 1 :(得分:4)
您正在区分不存在(或使用不常见的术语)。在Java术语中,监视器是用作同步块的参数的对象(或者,在同步实例方法的情况下,隐式地是this
实例,并且使用同步静态方法的类实例)。
答案 2 :(得分:3)
主要的是普通synchronized
块使用封闭对象作为其监视器,换句话说,它等同于使用synchronized(this) { }
。问题是范围/可见性问题:类外部的任何类都可以选择在同一实例上进行同步并干扰同步逻辑。通过使用private final
引用作为监视器,这是不可能的(假设没有反射恶作剧)。
这在Java Concurrency In Practice中制定如下(p61,第4.2.1节):
使用私有锁对象而不是对象的内部锁(或任何其他可公开访问的锁)是有好处的。使锁对象私有化会封锁锁,以便客户端代码无法获取它,而可公开访问的锁允许客户端代码正确或错误地参与其同步策略。不正当地获取另一个对象锁的客户端可能会导致活动性问题,并且验证正确使用可公开访问的锁需要检查整个程序而不是单个类。
答案 3 :(得分:2)
但在我看来,任何对象监视器逻辑都可以通过使用同步代码块和/或方法轻松替换。
是的,这是正确的,因为一杯水很容易被一杯水取代 - 它们是一样的。 Java的同步代码块和方法在语言级别公开monitor pattern。