【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 ...
随机推荐
- webpack4.x下babel的安装、配置及使用
前言 目前,ES6(ES2015)这样的语法已经得到很大规模的应用,它具有更加简洁.功能更加强大的特点,实际项目中很可能会使用采用了ES6语法的模块,但浏览器对于ES6语法的支持并不完善.为了实现兼容 ...
- Spring LDAP的使用
LDAP入门http://www.jianshu.com/p/7e4d99f6baaf Spring LDAP,是Spring的一个组件,实现对LDAP的操作. 在编程操作MySQL时,我们除了用JD ...
- Mobile Communication
最近面试有被问到LTE,感觉说得不太清楚,重新整理一遍. 一.第一代移动通信系统 1G,诞生于1980年左右.模拟通信系统,抗干扰性能差,使用FDMA技术,主要用来传输话音信号,最拉风的就是" ...
- [bzoj2427]P2515 [HAOI2010]软件安装(树上背包)
tarjan+树上背包 题目描述 现在我们的手头有 \(N\) 个软件,对于一个软件 \(i\),它要占用 \(W_i\) 的磁盘空间,它的价值为 \(V_i\).我们希望从中选择一些软件安装到一台磁 ...
- 给springboot增加XSS跨站脚本攻击防护功能
XSS原理 xss攻击的原理是利用前后端校验不严格,用户将攻击代码植入到数据中提交到了后台,当这些数据在网页上被其他用户查看的时候触发攻击 举例:用户提交表单时把地址写成:山东省济南市<scri ...
- 入职半年多,Guide哥总结了这些帮助你领先90%程序员的好习惯!
大家好,我是 Guide 哥,这篇文章还是不分享技术文章了,我想简单聊聊一些程序员的好习惯. 其实自己写这篇文章还是很忐忑的,毕竟自己算不上一个优秀的程序员,但也不是那么差.大学学习编程 4 年,工作 ...
- spring学习笔记(八)webSocket
知识储备 什么是stomp? 我们可以类比TCP与Http协议,我们知道Http协议是基于TCP协议的,Http协议解决了 web 浏览器发起请求以及 web 服务器响应请求的细节,我们在编码时候只要 ...
- Day_09【常用API】扩展案例8_计算字符'j'和字符串'java'在字符串中出现的次数
需求说明 定义如下字符串: String str = "javajfiewjavajfiowfjavagkljjava"; 请分别定义方法统计出: 1.字符串中:字符j的数量 2. ...
- 中文分词工具简介与安装教程(jieba、nlpir、hanlp、pkuseg、foolnltk、snownlp、thulac)
2.1 jieba 2.1.1 jieba简介 Jieba中文含义结巴,jieba库是目前做的最好的python分词组件.首先它的安装十分便捷,只需要使用pip安装:其次,它不需要另外下载其它的数据包 ...
- Intel x86
PCIe一般规则: purely平台 Intel UPI, Processor DMI3 (Rx lanes only), and Processor PCIe3 (Rx lanes only)Not ...