在Java中,监视器和锁的区别是什么
使用synchronized关键字方法,使用javap命令查看字节码,发现使用了monitor,如果在实现synchronized时可以调用monitor,这是我的理解,对吗?如果不正确,请更正它。他们之间的关系是什么?锁和监视器之间的关系是什么?在中,您可以找到问题的答案: 同步。Java编程语言提供了多种 线程间通信的机制。其中最基本的 方法是同步,使用监视器实现。每个 Java中的对象与监视器关联,监视器是线程 可以锁定或解锁在Java中,监视器和锁的区别是什么,java,locking,synchronized,Java,Locking,Synchronized,使用synchronized关键字方法,使用javap命令查看字节码,发现使用了monitor,如果在实现synchronized时可以调用monitor,这是我的理解,对吗?如果不正确,请更正它。他们之间的关系是什么?锁和监视器之间的关系是什么?在中,您可以找到问题的答案: 同步。Java编程语言提供了多种 线程间通信的机制。其中最基本的 方法是同步,使用监视器实现。每个 Java中的对象与监视器关联,监视器是线程 可以锁定或解锁 从官方文件: 同步是围绕一个称为内在锁或监视锁的内部实体构建
从官方文件:
- 同步是围绕一个称为内在锁或监视锁的内部实体构建的。(API规范通常将该实体简单地称为“监视器”)
- 每个对象都有一个与之关联的内在锁。按照惯例,线程必须获取对象的监视器锁 在访问它们之前,然后在关闭时释放监视器锁 他们完了。一个线程被称为在两个时间间隔内拥有锁 已获取锁并释放锁。只要线程拥有 一个监视器锁,没有其他线程可以获得相同的锁。其他的 线程在尝试获取锁时将阻塞
- 当一个线程释放锁时,在该操作和任何后续的数据获取之间建立关系之前,会发生一个错误 同样的锁
因此,不能将显示器和锁进行比较,它们是互补的。Java中的每个对象都与一个监视器相关联,线程可以锁定该监视器或解锁该监视器 锁是一种数据,在逻辑上是堆内存中对象头的一部分。JVM中的每个对象都有这个锁(或互斥锁),任何程序都可以使用它来协调对该对象的多线程访问。如果任何线程想要访问该对象的实例变量;然后线程必须“拥有”对象的锁(在锁内存区域中设置一些标志)。尝试访问对象变量的所有其他线程都必须等待,直到所属线程释放对象的锁(取消设置标志) 一旦一个线程拥有一个锁,它可以多次再次请求同一个锁,但是在其他线程可以使用该锁之前,它必须释放相同次数的锁。例如,如果一个线程请求锁三次,该线程将继续拥有该锁,直到它“释放”它三次 请注意,当线程显式请求锁时,锁是由线程获取的。在Java中,这是通过synchronized关键字或wait和notify完成的 监视器 Monitor是一种同步结构,它允许线程具有互斥(使用锁)和协作,即使线程等待特定条件为真(使用等待集)的能力 换句话说,除了实现锁的数据外,每个Java对象在逻辑上都与实现等待集的数据相关联。锁帮助线程在共享数据上独立工作而不相互干扰,而等待集则帮助线程相互协作以共同实现一个目标,例如,所有等待的线程都将移动到此等待集,一旦释放锁,所有等待的线程都将收到通知。此等待集有助于通过锁(互斥)的额外帮助构建监视器 有关更多说明,请参阅- 文档可能不是一个很好的地方来解释锁和监视器之间的区别,尤其是它提到的术语:
内在锁
,监视器锁
和简单的监视器
,这似乎表明监视器和锁是可互换的
事实并非如此
Monitor是一种用于多线程同步的结构。它由一个锁和几个条件变量组成。条件变量是一个队列,当给定条件不符合要求时,线程可以将其置于该队列中。当条件为真时,其他一些线程可以唤醒这些线程。条件变量是帮助线程相互协作的一种方法
在简单的同步情况下,我们只使用监视器提供的锁,如以下示例:
class SimpleCase {
int counter;
synchronized inc() int {
return counter++;
}
}
执行inc()
的线程不需要协作,只需锁定即可使线程互斥,从而使计数器
线程安全
而在更复杂的情况下,不仅需要互斥(mutex),还需要合作
例如,有界消费者/生产者问题:多消费者和生产者消费并向队列发送消息。需要协作,因为消息队列具有最大大小,当队列已满时,无法发送更多消息,当队列为空时,无法使用更多消息
以下是显示制作人的代码:
package monitor;
public class Producer {
BoundedQueue queue;
public Producer(BoundedQueue queue) {
this.queue = queue;
}
public void send(int msg) throws InterruptedException {
synchronized (queue) {
// wait till there is room to produce
while (queue.isFull()) {
queue.wait();
}
// business logic here
queue.add(msg);
System.out.println("sent:" + msg + ", from:" + Thread.currentThread().getName());
// before exit, call notify() to wake up waiting threads
queue.notifyAll();
}// implicit release the lock when exiting the synchronized block
}
}
在代码中,BoundedQueue
用作监视器,除了互斥之外,生产者和消费者还需要合作:当队列已满时,生产者需要wait()
,当队列有可用插槽时,生产者需要在向队列发送数据后,通知生产者从等待中醒来,它还需要调用notifyAll()
,以防消费者等待队列不为空的条件
这里,监视器提供了等待
和通知
的功能,以使线程协作
希望这能帮助您理解监视器和锁之间的区别
参考: