当前位置:网站首页>Synchronization lock synchronized traces the source
Synchronization lock synchronized traces the source
2022-08-09 23:12:00 【Learned Valley Wild Architects】
1 同步锁synchronized追本溯源
引言
提到synchronized,Both in the development process and the interview process often encountered problems
synchronized;It is also a disaster area
Why is it said to be the hardest hit area?
Because he is not like other codes,There is source code,可以查看的
synchronized是一个关键字.Can't find the source code directly
接下来
我们会通过javaMemory script and c++源码(HotSpot虚拟机源码)
Let us analyze itsynchronizedIn the end is how to achieve lock synchronization
1.1 synchronized场景回顾
目标:
synchronized回顾
概念
**synchronized:**是Java中的关键字,是一种同步锁.
synWhich lock category does it belong to:
乐观锁、悲观锁(syn)
独享锁(syn)、共享锁
公平锁、非公平锁(syn)
互斥锁(syn)、读写锁
可重入锁(syn)
tips:
synchronized JDK1.6锁升级 : 无锁 -> 偏向锁 (非锁)-> 轻量级锁 -> 重量级锁(1.6前都是)
多线程特性回顾(面试常问)
原子性:指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行
**可见性:**是指多个线程访问一个资源时,该资源的状态、值信息等对于其他线程都是可见的.
**有序性:**指程序中代码的执行顺序 (编译器会重排)
syncThe above three features can be fully implemented to ensure thread safety,casatomicity cannot be achieved.
这是什么原理呢?
1.2 反汇编寻找锁实现原理
目标
通过javap反汇编看一下synchronized到底是怎么加锁的
com.syn.BTest
public class BTest {
private static Object object = new Object();
public synchronized void testMethod() {
System.out.println("Hello World -synchronized method ");
}
public static void main(String[] args) {
synchronized (object) {
System.out.println("Hello World -synchronized block ");
}
}
}
反汇编后,我们将看到什么?
JDK自带的一个工具: javap ,对字节码进行反汇编:
//com.syn.BTest
javap -v -c BTest.class
-v:输出附加信息
-c:对代码进行反汇编
反汇编后
解释
被synchronized修饰的代码块,多了两个指令
monitorenter、monitorexit
即JVM使用monitorenter和monitorexit两个指令实现同步
解释
The method is checked when the method is called ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor.也就是jvm会隐式调用monitorenter和
monitorexit.
- monitorenter原理
monitorenter首先我们来看一下JVM规范中对于monitorenter的描述
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorenter
monitorenter :
Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
• If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
• If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
• If another thread already owns the monitor associated with objectref, the thread blocks until the monitor’s entry count is zero, then tries again to gain ownership.
monitorexit:
The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.
The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.
翻译如下:
- monitorenter
每一个对象都会和一个监视器monitor关联.
监视器被占用时会被锁住,其他线程无法来获取该monitor.
当JVM执行某个线程的某个方法内部的monitorenter时,It will try to get the current object corresponding
的monitor的所有权.其过程如下:
若monior的进入数为0,线程可以进入monitor,并将monitor的进入数置为1.当前线程成为
monitor的owner(所有者)若线程已拥有monitor的所有权,允许它重入monitor,则进入monitor的进入数加1
若其他线程已经占有monitor的所有权,那么当前尝试获取monitor的所有权的线程会被阻塞,直
到monitor的进入数变为0,才能重新尝试获取monitor的所有权.
- monitorexit
能执行monitorexit指令的线程一定是拥有当前对象的monitor的所有权的线程.
执行monitorexit时会将monitor的进入数减1.当monitor的进入数减为0时,当前线程退出
monitor,不再拥有monitor的所有权,此时其他被这个monitor阻塞的线程可以尝试去获取这个
monitor的所有权
monitorexit释放锁.
monitorexit插入在方法结束处和异常处,JVM保证每个monitorenter必须有对应的monitorexit.
tips(重要)
简单的理解,monitor就是jvm底层的c++代码中的一个对象ObjectMonitor.
There is a counter in this object,To record whether the current object lock is used by anyone,用了多少次.
and some queues,Store and schedule some threads that need this lock.
关于monitor在c++里的结构,We will go into more detail below.
总结:
1、synchronized是靠ObjectMonitorto control the lock
2、The thread that needs this lock is theremonitorThe queue is arranged in various ways
3、The thread that got the lock ismonitor标记,Count up,释放锁,需要将计数器减减操作
1.3 Monitor详解
目标:Monitor的位置
Next we look at its detailed internal structure,and how it works.
1.3.1 Monitor是什么
目标: 通过JVM虚拟机源码分析synchronized监视器Monitor到底是什么
tips:
c++You can understand the source code,The principle must be understood
It's important during the interview,面试过去了就不重要!(瞎说什么大实话)
在HotSpot虚拟机中,monitor监视器是由ObjectMonitor实现的.
构造器代码src/share/vm/runtime/objectMonitor.hpp
hpp可以include包含cpp的东西,两者都是c++的代码
//构造器
ObjectMonitor() {
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0; // 线程的重入次数
_object = NULL;
_owner = NULL; // 当前线程,The one who got the lock
_WaitSet = NULL; // 等待队列,调waitThe thread is here
_WaitSetLock = 0 ;
_Responsible = NULL;
_succ = NULL;
_cxq = NULL; // 竞争队列,Can't earn a lock to advance here(Spinable)
FreeNext = NULL;
_EntryList = NULL; // 阻塞队列,来自cxq(调unlock时)或者waitSet(调notify时)
_SpinFreq = 0;
_SpinClock = 0;
OwnerIsThread = 0;
}
Pay attention to these three lists:
1)cxq(Competitive list)
cxq是一个单向链表.A linked list of suspended threads waiting to re-compete for locks, monitor 通过CASwill be packaged intoObjectWaiterWrite to the head of the list.To avoid contention for inserting and removing elements,所以Ownerwill fetch elements from the end of the list.So this thing can be understood as the one who didn't get the lock when the competition came up and stayed here for a while(1级缓存).
2)EntryList(List of lock candidates)
EntryList是一个双向链表.当EntryList为空,cxq不为空,Owener会在unlock时,将cxq中的数据移动到EntryList.并指定EntryListThe first thread at the head of the list isOnDeck线程,The other threads just stay inside.So this thing can be considered as the secondary competition lock has not been obtained(One of them will be picked up soon).(2级缓存)
备注:EntryList跟cxq的区别
在cxqThe queue in can continue to spin waiting for the lock,Called if the spin threshold is reached and the lock is not acquiredpark方法挂起.而EntryListThe threads in are all suspended threads.
3)WaitList
WatiList是OwnerThread callwait()The thread entered after the method.进入WaitList中的线程在notify()/notifyAll()It will be added after the callEntryList.
过程总结:
- Threads waiting for the lock will stay_cxq和entry set队列中,The specific one is related to the situation of the current thread taking the lock
- entry setThe header thread gets the objectmonitor后进入_Owner区域并把monitor中的
_owner
The variable is set to itself,同时monitor中的计数器_count
加1 - 若线程调用
wait()
方法,将释放当前持有的monitor,_owner
变量恢复为null,_count
自减1,同时该线程进入_WaitSet
集合中等待被唤醒. - 若当前线程执行完毕也将释放monitor(锁)并复位变量的值,以便其他线程进入获取monitor(锁).
1.3.2 详细流程图(了解)
monitorenter
monitorentercommand execution location:
JVM源码:src/share/vm/interpreter/interpreterRuntime.cpp
JVM函数入口:InterpreterRuntime::monitorenter
最终调用:src/share/vm/runtime/objectMonitor.cpp中的 ObjectMonitor::enter
monitorexit
执行monitorexit指令位置:
代码文件:src/share/vm/runtime/objectMonitor.cpp
调用函数:ObjectMonitor::exit
专注Java技术干货分享,欢迎志同道合的小伙伴,一起交流学习
边栏推荐
- DSPE-PEG-Azide, DSPE-PEG-N3, phospholipid-polyethylene glycol-azide can react directly with DBCO
- gmail+mtalk配合打免费网络电话。
- Lyapp exponents and bifurcation diagrams for fractional chaotic systems
- 几种绘制时间线图的方法
- Unity_物体自转
- 题解:Edu Codeforces 109(div2)
- MySQL慢查询的多个原因
- CVPR22 Oral|通过多尺度token聚合分流自注意力,代码已开源
- Leetcode 93 复原IP地址
- UE4_定序器控制蓝图对象
猜你喜欢
角度和弧度的相互换算
Don't use array.length-1 to get the last item of the array
Don't tell me to play, I'm taking the PMP exam: what you need to know about choosing an institution for the PMP exam
URL Protocol web page to open the application
威纶通触摸屏制作自定义弹出窗口的具体方法(3种)
消防安全培训|“蓝朋友”,开课了!
Application of Acrel5000web Energy Consumption System in a College-Susie Week
[corctf 2022] section
抽象类 or 接口
PMP每日一练 | 考试不迷路-8.9(包含敏捷+多选)
随机推荐
STC8H development (15): GPIO drive Ci24R1 wireless module
题解:Edu Codeforces 109(div2)
gmail+mtalk配合打免费网络电话。
cad图纸怎么复制到word文档里面?Word里插CAD图怎么弄?
DSPE-PEG-PDP, DSPE-PEG-OPSS, phospholipid-polyethylene glycol-mercaptopyridine reduce the immunogenicity of peptides
Tensorflow中placeholder函数的用法
windos安装Mysql8.0,及解决重新登录异常问题 ERROR 1045 (28000)
角度和弧度的相互换算
SecureCRT背景配色
单元测试
【双链表增删查改接口的实现】
SQLi-LABS Page-2 (Adv Injections)
在VMware上安装win虚拟机
[Essay] To the friends of the 19th issue
哪款C语言编译器(IDE)适合初学者?
论文解读(DropEdge)《DropEdge: Towards Deep Graph Convolutional Networks on Node Classification》
《强化学习周刊》第57期:DL-DRL、FedDRL & Deep VULMAN
MySQL慢查询的多个原因
The round functions in the np, ceil function and floor function
Photometric Stereo 光度立体法三维重建