我在不同的博客中读过有关显示器的不同内容.所以我现在有点困惑.
据我所知,monitor是一个确保只有一个线程在关键部分执行代码的人.那么如果我们有3个同步的方法/块,那么我们将有3个监视器来确保只有一个线程在临界区?
如果以上是真的那么为什么说在Java中每个对象都有一个与之关联的监视器?它应该是每个同步块与监视器相关联.
什么是显示器?
监视器是线程可以抓取并保持的东西,防止所有其他线程抓取同一个监视器并强制它们等到监视器被释放.这就是一个synchronized
块.
这些显示器首先来自哪里?
答案是:来自任何Java对象.当你写:
Object foo = new Object();
synchronized (foo) {
System.out.println("Hello world.");
}
Run Code Online (Sandbox Code Playgroud)
......这意味着:当前线程将首先获取与存储在变量中的对象关联的监视器,foo
并在打印"Hello world"时保持它,然后释放它.
为什么每个Java对象都有一个与之关联的监视器?
它没有技术上的原因.这是在Java的早期版本中做出的设计决定,现在改变为时已晚(即使它最初很混乱,如果人们不小心它确实会引起问题).
使用synchronized
with blocks 时,您指定要锁定的对象。在这种情况下,该对象的监视器用于锁定。
使用synchronized
with 方法时,您不指定要锁定的对象,而是this
隐含对象。同样,监视器this
用于锁定。
因此,对象有监视器,同步方法/块没有自己的监视器,而是使用特定对象的监视器。
在 Java 编程的上下文中,监视器是 Java 对象上的内在锁(其中内在意味着“内置”)。对于要进入对象上的任何同步实例方法的线程,它必须首先获取该对象上的固有锁。对于要进入类上任何同步静态方法的线程,它必须首先获取该类上的内部锁。
这是Java 教程中定义监视器的方式:
同步是围绕称为内在锁或监视器锁的内部实体构建的。(API 规范通常将此实体简称为“监视器”。)
监视器属于一个对象,而不是单个块,这是有充分理由的:监视器的作用是保护对象的状态。对象应该被设计为具有内聚性,使得实例变量最终可能被多个方法引用;为了保证对象始终处于一致状态,安全的做法是一次只允许该对象上执行一个同步方法。
术语“监视器”来自Concurrent Pascal。请参阅Per Brinch Hansen 的论文“Java's Insecure Parallelism”,该论文认为 Java 实际上并未实现监视器:
Gosling (1996, p. 399) 声称 Java 使用监视器来同步线程。不幸的是,仔细检查发现 Java 不支持监视器概念:
除非声明为同步,否则 Java 类方法是不同步的。
除非声明为私有,否则 Java 类变量是公共的(在包内)
同一篇论文的另一段引用:
未能为线程交互赋予足够的含义是 Java 的一个非常严重的缺陷,它破坏了监视器概念的概念完整性。
归档时间: |
|
查看次数: |
3520 次 |
最近记录: |