java线程中的"Monitor"

Dee*_*mar 8 java

我在不同的博客中读过有关显示器的不同内容.所以我现在有点困惑.

据我所知,monitor是一个确保只有一个线程在关键部分执行代码的人.那么如果我们有3个同步的方法/块,那么我们将有3个监视器来确保只有一个线程在临界区?

如果以上是真的那么为什么说在Java中每个对象都有一个与之关联的监视器?它应该是每个同步块与监视器相关联.

biz*_*lop 9

什么是显示器?

监视器是线程可以抓取并保持的东西,防止所有其他线程抓取同一个监视器并强制它们等到监视器被释放.这就是一个synchronized块.

这些显示器首先来自哪里?

答案是:来自任何Java对象.当你写:

Object foo = new Object();
synchronized (foo) {
  System.out.println("Hello world.");
}
Run Code Online (Sandbox Code Playgroud)

......这意味着:当前线程将首先获取与存储在变量中的对象关联的监视器,foo并在打印"Hello world"时保持它,然后释放它.

为什么每个Java对象都有一个与之关联的监视器?

它没有技术上的原因.这是在Java的早期版本中做出的设计决定,现在改变为时已晚(即使它最初很混乱,如果人们不小心它确实会引起问题).

  • @DeepakKumar`ThisClass.class`也是一个Object(恰好是`Class`类的实例),该对象用于静态方法的同步. (2认同)

Mik*_*kis 5

使用synchronizedwith blocks 时,您指定要锁定的对象。在这种情况下,该对象的监视器用于锁定。

使用synchronizedwith 方法时,您不指定要锁定的对象,而是this隐含对象。同样,监视器this用于锁定。

因此,对象有监视器,同步方法/块没有自己的监视器,而是使用特定对象的监视器。


Nat*_*hes 5

在 Java 编程的上下文中,监视器是 Java 对象上的内在锁(其中内在意味着“内置”)。对于要进入对象上的任何同步实例方法的线程,它必须首先获取该对象上的固有锁。对于要进入类上任何同步静态方法的线程,它必须首先获取该类上的内部锁。

这是Java 教程中定义监视器的方式:

同步是围绕称为内在锁或监视器锁的内部实体构建的。(API 规范通常将此实体简称为“监视器”。)

监视器属于一个对象,而不是单个块,这是有充分理由的:监视器的作用是保护对象的状态。对象应该被设计为具有内聚性,使得实例变量最终可能被多个方法引用;为了保证对象始终处于一致状态,安全的做法是一次只允许该对象上执行一个同步方法。

术语“监视器”来自Concurrent Pascal。请参阅Per Brinch Hansen 的论文“Java's Insecure Parallelism”,该论文认为 Java 实际上并未实现监视器:

Gosling (1996, p. 399) 声称 Java 使用监视器来同步线程。不幸的是,仔细检查发现 Java 不支持监视器概念:

  • 除非声明为同步,否则 Java 类方法是不同步的。

  • 除非声明为私有,否则 Java 类变量是公共的(在包内)

同一篇论文的另一段引用:

未能为线程交互赋予足够的含义是 Java 的一个非常严重的缺陷,它破坏了监视器概念的概念完整性。