【Java】【JVM】Sychronized底层加锁原理详解
- 我们首先先看看JMM模型,话不多说,上图:
- JMM对应的8大原子操作:
read(读取):从主内存读取数据
load(载入):将主内存读取到的数据写入工作内存
use(使用):从工作内存读取数据来计算
assign(赋值):将计算好的值重新赋值到工作内存中
store(存储):将工作内存数据写入主内存
write(写入):将store过去的变量赋值给主内存中的变量
lock(锁定):将主内存变量加锁,标示为线程独占状态
unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
- Sychronized底层对应的JMM模型8大原子操作【lock】和【unlock】
- 此时即可同时保持
- 【原子性】:代码成块
- 【有序性】
- 【可见性】
感兴趣的同学,可以对代码编译后,看下反编译后的指令,此处我们分析一下:
- 原理:
- JVM内置锁通过synchronized使用,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex Lock(互斥锁)实现,它是一个重量级锁,性能较低。
- 如果此时存在一个object2,那么当object1对应线程结束后,只唤醒object1对应阻塞队列中的线程:
- Monitor加锁原理:每个同步对象都有一个自己的Monitor(锁监视器)
- JVM加锁过程:JVM内置锁,有没有办法能够手动控制加锁与解锁?
- JDK1.6版本之后对synchronized的实现进行了各种优化,如适应性自旋锁、轻量级锁和偏向锁,并默认开启偏向锁
开启偏向锁:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay= 关闭偏向锁:-XX:-UseBiasedLocking
上面详细说了一下重量级锁,如果是轻量级锁,那么就没有对应的【Monitor】监视类,那么轻量级锁是如何进行区分的呢?
- 来!这里看一下对象结构,不墨迹,撸图:
- 这里张贴一段jdk源代码(有些深度)
oop.hpp: class oopDesc {
friend class VMStructs;
private:
volatile markOop _mark;
union _metadata {
Klass* _klass;
narrowKlass _compressed_klass;
} _metadata;
markOop.hpp:
// 32 bits:
// --------
// hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object) #正常的对象状态
// JavaThread*:23 epoch:2 age:4 biased_lock:1 lock:2 (biased object) #偏向锁的对象状态
// size:32 ------------------------------------------>| (CMS free block)
// PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
//
// 64 bits:
// --------
// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object)
// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object)
// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
// size:64 ----------------------------------------------------->| (CMS free block)
- 这里Mark Word在32位JVM中存储内容为例:
- 问题又来了,那么JVM内置锁升级优化过程是如何的呢?
- 偏向锁高效原因:
只需要修改【Object Mark Word】中的【hashcode】标志位为当前线程对应的【Thread ID】;
而如果直接切换到重量级锁,则是一个用户态到内核态的切换。
- 偏向锁可以被撤销么?
当然可以被撤销,不过要等到当前拥有锁的线程达到安全点,即执行完同步块,才可以撤销。
【Java】【JVM】Sychronized底层加锁原理详解的更多相关文章
- Java精通并发-synchronized关键字原理详解
关于synchronized关键字原理其实在当时JVM的学习[https://www.cnblogs.com/webor2006/p/9595300.html]中已经剖析过了,这里从研究并发专题的角度 ...
- 高性能的Redis之对象底层实现原理详解
对象 在前面的数个章节里, 我们陆续介绍了 Redis 用到的所有主要数据结构, 比如简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合, 等等. Redis 并没有直接使用这些数据结构来实 ...
- java环境配置及原理详解
java环境配置及原理详解 1.java跨平台的本质 我们谈到java,总是提到跨平台这个词.那么java语言是怎么实现跨平台的呢? 我们编写的java代码不是直接让windows系统读取解析,而是在 ...
- 通过 JFR 与日志深入探索 JVM - TLAB 原理详解
全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇 什么是 TLAB? TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,这是一个线程专用的内存分配 ...
- 线程池底层原理详解与源码分析(补充部分---ScheduledThreadPoolExecutor类分析)
[1]前言 本篇幅是对 线程池底层原理详解与源码分析 的补充,默认你已经看完了上一篇对ThreadPoolExecutor类有了足够的了解. [2]ScheduledThreadPoolExecut ...
- Spring Aop底层原理详解
Spring Aop底层原理详解(来源于csdn:https://blog.csdn.net/baomw)
- 【转载】JAVA消息服务JMS规范及原理详解
转载:https://www.cnblogs.com/molao-doing/articles/6557305.html 作者: moyun- 一.简介 JMS即Java消息服务(Java Messa ...
- JAVA消息服务JMS规范及原理详解
JAVA消息服务JMS规范及原理详解 一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应 ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
随机推荐
- CCS进阶——div的宽度和高度是由什么决定的?
核心知识 文档流/普通流(Normal Flow) 内联元素的宽高(高度是由行高决定的,宽度=内容+border+marging+padding) 块级元素的宽高(高度是内部文档流元素的高度总和,宽度 ...
- 无法打开到SQL Server的连接 (Microsoft SQL Server, 错误:53) .
标题: 连接到服务器 ------------------------------ 无法连接到 MSSQLSERVER. ------------------------------ 其他信息: 在与 ...
- pvresize
lvm pv 扩容 pvresize 当PV对应的设备分区(如md软raid)扩容之后,利用该命令可以扩容PV
- H3C配置Web登陆
为什么80%的码农都做不了架构师?>>> 1.开启http服务. [H3C]ip http enable 2.创建web登陆的用户. [H3C]local-user king / ...
- SQL Server遍历表中记录的2种方法
SQL Server遍历表一般都要用到游标,SQL Server中可以很容易的用游标实现循环,实现SQL Server遍历表中记录.本文将介绍利用使用表变量和游标实现数据库中表的遍历. 表变量来实现表 ...
- 使用Xamarin开发即时通信系统 -- 基础篇(大量图文讲解 step by step,附源码下载)...
如果是.NET开发人员,想学习手机应用开发(Android和iOS),Xamarin 无疑是最好的选择,编写一次,即可发布到Android和iOS平台,真是利器中的利器啊!而且,Xamarin已经被微 ...
- 数学--数论--POJ1365——Prime Land
Description Everybody in the Prime Land is using a prime base number system. In this system, each po ...
- 图论--BFS总结
1.关于BFS的Key_word: ①hash或状态压缩记录状态 ②状态剪枝 ③反向BFS ④双向BFS ⑤特殊初始化VIS数组 ⑥动态图的搜索 ⑦优先队列优化搜索 ⑧数位搜索 下面是一一讲解: 1 ...
- java基础知识备忘
1.java内存分配 a.寄存器cup -- 暂不涉及 b.本地方法栈 -- 虚拟机调用windows功能用的,比如创建文件夹 c.方法区 -- 存放 .class文件,负责存放方法 d.栈 -- ...
- [蓝桥杯2018初赛]小朋友崇拜圈(dfs找环)
传送门 思路: 题意大意:n条有向边,找出最大环. 我们发现,如果一个小朋友没有被任何人崇拜,那么他一定不位于环中.为此我们可以设置一个indug数组预处理.如果2被崇拜了那么indug[2]就加加, ...