在Java中,监视器和锁之间有什么区别

时间:2018-04-02 11:43:03

标签: java locking synchronized

使用synchronized关键字方法,使用javap命令查看字节码,发现使用了监视器,如果可以在实现synchronized时调用监视器,那是我的理解,对吧?如果不这样做,请更正。他们之间有什么关系?锁和显示器之间有什么关系?

5 个答案:

答案 0 :(得分:3)

  

来自锁和的官方文档   同步https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html):

     
      
  • 同步是围绕称为 内在锁 监视锁 的内部实体构建的。
  •   
  • 每个对象都有一个与之关联的内在锁。按照惯例,线程必须获取对象的监视器锁   在访问它们之前,然后释放监视器锁   完成他们。据说一个线程拥有它之间的锁定时间   获得了锁并释放了锁。只要一个线程拥有   一个监视器锁,没有其他线程可以获得相同的锁。另一个   线程在尝试获取锁时会阻塞。
  •   
  • 当线程释放锁定时,会在该操作与之后的任何后续获取之间建立先发生关系   同样的锁。
  •   

因此,无法比较监视器和锁定器之间的差异,而是相互补充。 Java中的每个对象都与一个监视器相关联,该监视器可以锁定解锁

答案 1 :(得分:1)

this document中,您可以找到问题的答案:

  

同步。 Java编程语言提供了多种功能   线程之间通信的机制。其中最基本的   方法是同步,使用监视器实现。每   Java中的对象与监视器关联,后者是一个线程   可以锁定或解锁。

答案 2 :(得分:1)

<强>锁

锁是一种数据,逻辑上是堆内存中对象头的一部分。 JVM中的每个对象都具有此锁(或互斥锁),任何程序都可以使用该锁来协调对对象的多线程访问。如果任何线程想要访问该对象的实例变量;然后线程必须“拥有”对象的锁(在锁定存储区中设置一些标志)。尝试访问对象变量的所有其他线程必须等到拥有线程释放对象的锁(取消设置标志)。

一旦一个线程拥有一个锁,它就可以多次再次请求同一个锁,但是在它被其他线程使用之前必须释放相同的次数。例如,如果一个线程请求锁三次,那么该线程将继续拥有锁,直到它“释放”它三次。

请注意,当明确要求时,线程会获取锁定。在Java中,这是通过synchronized关键字或wait和notify来完成的。

<强>显示器

Monitor是一种同步结构,它允许线程同时具有互斥(使用锁定)和协作,即使线程等待某些条件为真的能力(使用wait-set)。

换句话说,与实现锁定的数据一起,每个Java对象在逻辑上与实现等待的数据相关联。锁可以帮助线程独立地在共享数据上工作而不会相互干扰,而等待集可以帮助线程彼此协作以共同努力实现共同目标,例如:所有等待的线程都将被移动到此等待集,并且一旦锁定被释放,所有线程都会收到通知。这个等待集有助于构建监视器,并提供锁定(互斥)的额外帮助。

有关更多说明,请参阅 -

UNDERSTANDING THREADS, MONITORS AND LOCKS

Difference between lock and monitor – Java Concurrency

答案 3 :(得分:1)

文档https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html可能不是找出Lock和Monitor之间的区别的好地方,尤其是它提到的术语:intrinsic lockmonitor lock和简单的{{1} },这似乎表明监视器和锁定可以互换。

这不是真的。

Monitor是用于多线程同步的结构。它由一个锁和几个条件变量组成。条件变量是一个队列,线程可以在给定条件不符合要求时将其置于队列中。条件成立时,其他一些线程可以唤醒这些线程。条件变量是一种帮助线程彼此协作的方法。

在简单的同步情况下,我们仅使用提供的监视器锁定,例如以下示例:

monitor

class SimpleCase { int counter; synchronized inc() int { return counter++; } } 的线程不需要合作,只需锁定就可以使线程互斥,从而使inc()线程安全。

在更复杂的情况下,不仅需要互斥(mutex),而且还需要合作。

例如,有限的消费者/生产者问题:多个消费者和生产者消费并将消息发送到队列。需要合作,因为消息队列具有最大大小,当队列已满时,不能再发送任何消息,而当队列为空时,就不能再使用任何消息。

下面是显示生产者的代码:

counter

在代码中,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(),以防万一有消费者在等待以下条件:队列不为空。

在这里,Monitor提供了notifyAll()wait的功能来使线程相互配合。

希望这有助于您了解Monitor和Lock之间的区别。

参考:

答案 4 :(得分:0)

monitor 是互斥、等待外部条件为真的能力以及将该事件通知其他线程的能力的组合。 条件和通知部分本质上是 cooperation

A lock 提供互斥。这意味着它可以防止多个线程同时访问相同的数据。

注意监视器使用互斥。因此,使用锁来实现监视器。