Juc19_从字节码角度看synchronize、Monitor类、monitorenter、monitorexit、深入理解同步方法(二)

简介: ③. Monitor类④. monitorenter

③. Monitor类


①. 前言:是在Java中万物皆是对象,所以这些指令(monitorenter、 monitorexit)会不会和某些对象有关系呢? 果然可以和一个叫Monitor类联系到一块


②. monitor相当于一个对象的钥匙,只有拿到此对象的monitor,才能访问该对象的同步代码。相反未获得monitor的只能阻塞来等待持有monitor的线程释放monitor。可以这样比喻吧,monitorenter 和monitorexit 对应的就是拿钥匙和还钥匙


③. Monitor与java对象以及线程是如何关联 ?


首先,每一个对象都有一个属于自己的monitor,其次如果线程未获取到singal (许可),则线程阻塞。object可以比作医院的诊室,monitor 就是负责喊病人的护士,线程则是就诊的病人。


通过护士(监视器)的调度,诊室(synchronized锁住的对象)内只允许进入一个病人(线程),此病人(线程)在当前时间就拥有此诊室(对象)的使用权,也就是获取了许可。病人就诊完毕,则表明归还了诊室的使用权。然后护士再调度下一个等待的病人进入诊室(被阻塞的线程)。走廊当中等待的病人们


④. 通过上面两段描述,我们应该能很清楚的看出Synchronized的实现原理,Synchronized的语义底层是通过一个monitor的对象来 完成,其实wait/notify等方法也依赖于monitor对象,这就是为什么只有在同步的块或者方法中才能调用wait/notify等方法,否则会抛出java.lang.IllegalMonitorState Exception的异常的原因


④. monitorenter


①. 每一个对象都会和一个监视器monitor关联。监视器被占用时会被锁住,其他线程无法来获取该monitor。当JVM执行某个线程的某个方法内部的monitorenter时,它会尝试去获取当前对象对应的monitor的所有权。其过程如下:


若monior的进入数为0,线程可以进入monitor,并将monitor的进数置为1。当前线程成为monitor的owner(所有者)


若线程已拥有monitor的所有权,允许它重入monitor,则进入monitor的进入数加1


若其他线程已经占有monitor的所有权,那么当前尝试获取monitor的所有权的线程会被阻塞,直到monitor的进入数变为0,才能重新尝试获取monitor的所有权


②. synchronized的锁对象会关联一个monitor,这个monitor不是我们主动创建的,是JVM的线程执行到这个同步代码块,发现锁对象没有monitor就会创建monitor,monitor内部有两个重要的成员变量owner:拥有这把锁的线程,recursions会记录线程拥有锁的次数,当一个线程拥有monitor后其他线程只能等待



相关文章
|
7月前
|
存储 安全 Java
synchronized原理-字节码分析、对象内存结构、锁升级过程、Monitor
本文分析的问题: 1. synchronized 字节码文件分析之 monitorenter、monitorexit 指令 2. 为什么任何一个Java对象都可以成为一把锁? 3. 对象的内存结构 4. 锁升级过程 (无锁、偏向锁、轻量级锁、重量级锁) 5. Monitor 是什么、源码查看(hotspot虚拟机源码) 6. JOL工具使用
|
5月前
|
存储 SQL 安全
Java共享问题 、synchronized 线程安全分析、Monitor、wait/notify以及锁分类
Java共享问题 、synchronized 线程安全分析、Monitor、wait/notify以及锁分类
48 0
|
7月前
|
Java 程序员 编译器
Monitor(管程)是什么意思?Java中Monitor(管程)的介绍
Monitor(管程)是什么意思?Java中Monitor(管程)的介绍
99 1
|
设计模式 数据挖掘 C++
C++并发与多线程(三)单例设计模式与共享数据分析、call_once、condition_variable使用
C++并发与多线程(三)单例设计模式与共享数据分析、call_once、condition_variable使用
140 0
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(四)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(四)
|
安全 Java API
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(一)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(一)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(二)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(二)
|
Linux 调度
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(三)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(三)
|
安全 Java 编译器
多线程安全问题原理和解决办法Synchronized和ReentrantLock使用与区别
多线程安全问题原理和解决办法Synchronized和ReentrantLock使用与区别
Jvm源码剖析之synchronized锁机制执行原理
Jvm源码剖析之synchronized锁机制执行原理
Jvm源码剖析之synchronized锁机制执行原理