Monitor (the tube) What does it mean? Java, Monitor (the tube) Introduction

The contents of this article is to bring about the Monitor (the tube) What does it mean? Java, Monitor (the tube) is introduced, there is a certain reference value, a friend in need can refer to, I hope for your help.

The concept of monitor

Tube side, English is the Monitor, also often translated as "monitor" monitor whether it is translated as "the tube" or "Monitor", are more obscure, by the Chinese translation, and can not reach a monitor intuitive description.
In the "OS synchronization primitives" this article describes some synchronization primitives operating system in the face of inter-process / thread synchronization, supported, where semaphore semaphores and mutex mutex is the most important synchronization primitive.
When using basic mutex concurrency control, programmers need to very carefully control the down and up mutex operation, it will easily lead to deadlock and other issues. To make it easier to write correct concurrent programs, so on the basis of the mutex and semaphore, a higher-level synchronization primitives monitor, but it needs to be noted that the operating system itself does not support monitor mechanism, in fact, monitor It falls under the category of programming languages, when you want to use the monitor, to find out whether the language itself supports monitor primitives, such as C language it does not support the monitor, Java language support monitor.
General monitor implementation pattern is provided on the programming language syntax syntactic sugar, and how to monitor mechanism, then the job belongs to the compiler, Java is so dry.

Monitor important feature is that the same time, only one process / thread can enter the critical region defined in the monitor, which makes the monitor can achieve mutually exclusive effect. But there are only exclusive role is not enough, can not enter the process monitor critical section / thread, they should be blocked, and wakes up when necessary. Clearly, monitor as a synchronization tool, it should also provide a mechanism for such a management process / thread state. Think about why we feel semaphore and mutex prone to error in the programming, because we need to go personally to operating variables and process / thread blocking and wake up. monitor this mechanism is called "higher-level primitives", then it will inevitably need to block out the mechanisms of external and internal mechanisms to achieve these, so that people use the monitor to see is a simple and easy to use interface.

monitor basic elements

monitor mechanism requires several elements to cope with, namely:

  1. Critical section

  2. monitor and lock objects

  3. And a wait condition variables defined on a monitor object, signal operation.

The purpose is mainly to monitor the mechanism of mutual exclusion to enter the critical section, in order to be able to do the blocking process can not enter the critical section / thread, you also need a monitor object to assist, the monitor object will have a corresponding internal data structures such as lists, to save the blocked thread; at the same time because it is based on this fundamental mutex primitives essentially monitor mechanism, so the monitor object must also maintain a lock mutex based.
In addition, in order to be able to wake up blocking and process / thread at the appropriate time, you also need to introduce a condition variable, the variable is used to determine when conditions are "appropriate time", this condition can be derived from the logic of the program code, it can be in monitor object interior, all in all, programmers have great autonomy to define the condition variable. However, due to monitor internal object uses a data structure to hold the queue is blocked, it must also provide external API to allow two thread into the blocked state and after being awakened, namely wait and notify.

Java language support for the monitor

monitor the operating system is proposed by a high-level primitives, but the specific implementation patterns, different programming languages ​​are likely to be different. The following Java to the monitor as an example to explain monitor implementation in Java.

Delineation of critical areas

In Java, the keyword can be used to modify the synchronized instance method, the method and the class code block, as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

 * @author beanlam

 * @version 1.0

 * @date 2018/9/12

 */

public class Monitor {

 

    private Object ANOTHER_LOCK = new Object();

 

    private synchronized void fun1() {

    }

 

    public static synchronized void fun2() {

    }

 

    public void fun3() {

        synchronized (this) {

        }

    }

 

    public void fun4() {

        synchronized (ANOTHER_LOCK) {

        }

    }

}

The modified method synchronized keyword, code blocks, is the critical area monitor mechanism.

monitor object

可以发现,上述的 synchronized 关键字在使用的时候,往往需要指定一个对象与之关联,例如 synchronized(this),或者 synchronized(ANOTHER_LOCK),synchronized 如果修饰的是实例方法,那么其关联的对象实际上是 this,如果修饰的是类方法,那么其关联的对象是 this.class。总之,synchronzied 需要关联一个对象,而这个对象就是 monitor object。
monitor 的机制中,monitor object 充当着维护 mutex以及定义 wait/signal API 来管理线程的阻塞和唤醒的角色。
Java 语言中的 java.lang.Object 类,便是满足这个要求的对象,任何一个 Java 对象都可以作为 monitor 机制的 monitor object。
Java 对象存储在内存中,分别分为三个部分,即对象头、实例数据和对齐填充,而在其对象头中,保存了锁标识;同时,java.lang.Object 类定义了 wait(),notify(),notifyAll() 方法,这些方法的具体实现,依赖于一个叫 ObjectMonitor 模式的实现,这是 JVM 内部基于 C++ 实现的一套机制,基本原理如下所示:

当一个线程需要获取 Object 的锁时,会被放入 EntrySet 中进行等待,如果该线程获取到了锁,成为当前锁的 owner。如果根据程序逻辑,一个已经获得了锁的线程缺少某些外部条件,而无法继续进行下去(例如生产者发现队列已满或者消费者发现队列为空),那么该线程可以通过调用 wait 方法将锁释放,进入 wait set 中阻塞进行等待,其它线程在这个时候有机会获得锁,去干其它的事情,从而使得之前不成立的外部条件成立,这样先前被阻塞的线程就可以重新进入 EntrySet 去竞争锁。这个外部条件在 monitor 机制中称为条件变量。

synchronized 关键字

synchronized 关键字是 Java 在语法层面上,用来让开发者方便地进行多线程同步的重要工具。要进入一个 synchronized 方法修饰的方法或者代码块,会先获取与 synchronized 关键字绑定在一起的 Object 的对象锁,这个锁也限定了其它线程无法进入与这个锁相关的其它 synchronized 代码区域。

网上很多文章以及资料,在分析 synchronized 的原理时,基本上都会说 synchronized 是基于 monitor 机制实现的,但很少有文章说清楚,都是模糊带过。
参照前面提到的 Monitor 的几个基本元素,如果 synchronized 是基于 monitor 机制实现的,那么对应的元素分别是什么?
它必须要有临界区,这里的临界区我们可以认为是对对象头 mutex 的 P 或者 V 操作,这是个临界区
那 monitor object 对应哪个呢?mutex?总之无法找到真正的 monitor object。
所以我认为“synchronized 是基于 monitor 机制实现的”这样的说法是不正确的,是模棱两可的。
Java 提供的 monitor 机制,其实是 Object,synchronized 等元素合作形成的,甚至说外部的条件变量也是个组成部分。JVM 底层的 ObjectMonitor 只是用来辅助实现 monitor 机制的一种常用模式,但大多数文章把 ObjectMonitor 直接当成了 monitor 机制。
我觉得应该这么理解:Java 对 monitor 的支持,是以机制的粒度提供给开发者使用的,也就是说,开发者要结合使用 synchronized 关键字,以及 Object 的 wait / notify 等元素,才能说自己利用 monitor 的机制去解决了一个生产者消费者的问题。

Guess you like

Origin blog.csdn.net/sinolover/article/details/95060114