有必要使用"监视器"对象(Java)吗?

3
我曾多次见到Java中使用对象监视器,但我认为任何对象监视器逻辑都可以轻松地通过使用同步代码块和/或方法来替代。使用显式对象监视器的目的是什么,而不仅仅是仔细协调同步代码块以及原子基元?

我认为你需要更具体地说明你的问题。你所说的“对象监视器逻辑”是什么意思?在标准的Java术语中,当你使用“synchronized”时,你会获得一个监视器锁。这是让你感到困惑的原因吗? - Jochen
我见过将对象声明并用作监视器的情况。通常情况下,我认为你可以使用简单的布尔值或同步块来实现典型的监视器/notifyAll逻辑,而不是使用任意对象。 - jayunit100
4个回答

4

始终存在一个监视器对象。当您使用同步块时,您的类实例是监视器对象。

因此,使用显式对象的原因:

1)您可以在类实例之间共享它们,以同步访问共享资源

2)更加明确

3)您可以为监视器对象指定有用的名称

4)更加灵活


4

您在区分不存在的事情(或者使用不常见的术语)。在Java术语中,监视器是用作synchronized块参数的对象(或者,在同步实例方法的情况下,隐式地使用this实例,并且在同步静态方法中使用类实例)。


3
主要问题在于普通的synchronized块使用封闭对象作为其监视器,换句话说,它相当于使用synchronized(this) { }。问题是作用域/可见性:任何外部类都可以选择在相同实例上进行同步并干扰您的同步逻辑。通过使用private final引用作为监视器,这就不再可能(假设没有反射猫腻)。
这在Java Concurrency In Practice中如下表述(第4.2.1节,第61页):

使用私有锁对象而不是对象的内在锁定(或任何其他公共可访问锁)具有优点。将锁对象设置为私有封装了锁,使客户端代码无法获取它,而公共可访问锁允许客户端代码参与其同步策略 - 正确或不正确。错误地获取另一个对象的锁的客户端可能会引起活力问题,验证公共可访问锁是否正确使用需要检查整个程序而不是单个类。


2
“但我认为,任何对象监视器逻辑都可以很容易地通过使用同步代码块和/或方法来替换。” “是的,这是正确的,因为它们是相同的东西,就像一杯水可以很容易地被另一杯水代替一样。Java的同步代码块和方法在语言级别上暴露了监视器模式。”

我相当喜欢它。我不同意它是一条评论。 - duffymo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接