面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
写在开头
面试官:小伙子,多线程中锁用过吗?
我:那是自然!
面试官:那你知道synchronized的优化吗?
我:synchronized作为重锁,开销大,在早期不被推荐使用,后期进行了优化,至于怎么优化的话,您让我想想哈...
面试官:好的,那你出去好好想吧!
对于synchronized的优化,虽然被问到的场景不多,但在很多网友发的面经中发现很多人都会挂在这个点上。
在我们初学锁时,很多人可能都觉得它是一个重量级锁,代码中不建议使用,但其实现如今经过了层层优化后,synchronized被广泛的应用在了JVM源码以及众多开源框架中,我们今天就来一起学习一下synchronized的优化过程!
对象锁的四种状态
首先,我们这里要记住一个Java迭代版本JDK1.6,这个版本对于synchronized来说是划时代的,在此之前,synchronized确实是一种重量级悲观锁,这个时候的它使用起来极耗资源,为所有高效开发者所弊病,但在1.6版本之后,引入了“偏向锁”和“轻量级锁” 的概念,这极大减少了获取synchronized锁和释放锁所需资源,synchronized重获新生!
在此之后,对象的锁便拥有了4种状态,根据锁的级别从低到高可分为:
无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁
无锁
无锁其实很好理解,就是没有对共享资源进行任何锁定,所有线程都可以去访问并修改同一资源,但同时只能有一个线程修改成功,其他线程不断尝试直至成功,并会将原内容覆盖。
偏向锁
偏向锁,指的就是偏向第一个加锁线程,对象的代码一直被同一线程执行,不存在多个线程竞争,该线程在后续的执行中自动获取锁,降低获取锁带来的性能开销。
轻量级锁
轻量级锁是指当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。
重量级锁
指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。
重量级锁通过对象内部的监视器(monitor)实现,而其中 monitor 的本质是依赖于底层操作系统的 Mutex Lock 实现,操作系统实现线程之间的切换需要从用户态切换到内核态,切换成本非常高。所以在没有被优化之前,synchronized这种重量级锁,才不受重视!

对象锁的存储
学习完对象锁的四种状态后,我们继续思考下一个问题,既然对象锁有四种状态,那它们是存储在哪里的呢?
会联想的同学,我想已经猜出了大概,首先在Java中的锁都是基于对象的,既然基于对象,那它存在的地方大概率要在对象中,而我们知道在JVM中,对象分为三个部分对象头、实例数据、字节对齐,其中对象头又由Mark Word和Klass Point构成,而Mark Word(标记字段)用于存储对象自身的运行时数据,例如存储对象的HashCode,分代年龄、锁标志位等信息,是synchronized实现轻量级锁和偏向锁的关键。我们64位虚拟机为例看下图:

当对象状态是偏向锁时,MarkWord中存储了偏向线程的ID,并且将是否偏向标志置为1;当对象状态是轻量级锁时,Mark Word存储的是指向线程栈中Lock Record的指针;当状态为重量级锁时,Mark Word为指向monitor(监视器)对象的指针。
synchronized 锁升级的过程
有了上面的知识储备,我们趁着打铁,来聊一聊synchronized 锁升级的过程,由低到高,逐渐升级。
1️⃣首先,在锁对象的对象头里面有一个 threadid 字段,未访问时 threadid 为空,这时是无锁状态,任何线程都可竞争获取共享资源;
2️⃣ 先得到共享资源的线程,其线程ID会被记录到Mark Word中,此时锁状态为偏向锁;
3️⃣ 当后续还有线程去获取共享资源时,会先判断 threadid 是否与其线程 id 一致。如果一致则可以直接使用此对象;如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁;
4️⃣自旋的线程在自旋过程中,成功获得资源(即之前获的资源的线程执行完成并释放了共享资源),则整个状态依然处于 轻量级锁的状态,如果自旋失败 。
5️⃣进入重量级锁的状态,这个时候,自旋的线程进行阻塞,等待之前线程执行完成并唤醒自己。
结尾彩蛋
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!

面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!的更多相关文章
- 【填坑往事】Android手机锁屏人脸解锁优化过程实录
背景 写这篇文章,主要是为了以后面试方便.因为我简历上写了,上一份工作的最大亮点是将人脸解锁的速度由1200ms优化到了600ms,所以这些内容已经回答无数遍了.但每次总觉得回答的不完整,或者说总感觉 ...
- 老掉牙的 synchronized 锁优化,一次给你讲清楚!
我们都知道 synchronized 关键字能实现线程安全,但是你知道这背后的原理是什么吗?今天我们就来讲一讲 synchronized 实现线程同步背后的原因,以及相关的锁优化策略吧. synchr ...
- 记一次Sql优化过程
这几天在写一个存储过程,反复优化了几次,从最开始的7分钟左右,优化到最后的几秒,并且这个过程中我的导师帮我指点了很多问题,这些指点都是非常宝贵的,独乐乐不如众乐乐,一起来分享这次的优化过程吧. 这个存 ...
- Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- 并发-Synchronized底层优化(偏向锁、轻量级锁)
Synchronized底层优化(偏向锁.轻量级锁) 参考: http://www.cnblogs.com/paddix/p/5405678.html 一.重量级锁 上篇文章中向大家介绍了Synchr ...
- Java多线程系列 基础篇07 synchronized底层优化
转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...
- java多线程02-----------------synchronized底层实现及JVM对synchronized的优化
java多线程02-----------------synchronized底层实现及JVM对synchronized的优化 提到java多线程,我们首先想到的就是synchronized关键字,它在 ...
- 【转】Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
一.重量级锁 上篇文章中向大家介绍了Synchronized的用法及其实现的原理.现在我们应该知道,Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的.但是监视器锁本 ...
- Synchronized底层优化(轻量级锁、偏向锁)(二)
一.重量级锁 上篇文章中向大家介绍了Synchronized的用法及其实现的原理.现在我们应该知道,Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的.但是监视器锁本质 ...
- php面试专题---MySQL常用SQL语句优化
php面试专题---MySQL常用SQL语句优化 一.总结 一句话总结: 原理,万变不离其宗:其实SQL语句优化的过程中,无非就是对mysql的执行计划理解,以及B+树索引的理解,其实只要我们理解执行 ...
随机推荐
- NC21467 [NOIP2018]货币系统
题目链接 题目 题目描述 在网友的国度中共有n种不同面额的货币,第i种货币的面额为a[i],你可以假设每一种货币都有无穷多张.为了方便,我们把货币种数为n.面额数组为a[1..n]的货币系统记作(n, ...
- Ubuntu 20.04 出现 SSL_connect: error:1425F102 .. unsupported protocol问题的解决
在安装完Ubuntu 20.04后, 这个问题影响了好几个软件, 包括MySQL Workbench, Openfortigui等等, 出现的错误都是 ERROR: SSL_connect: erro ...
- Map与WeakMap
Map与WeakMap Map对象用来保存键值对,并且能够记住键的原始插入顺序,任何对象或者原始值都可以作为键或者是值. WeakMap对象同样用来保存键值对,对于键是弱引用的而且必须为一个对象,而值 ...
- ftp 出现Passive mode refused 解决办法
在shell中调用FTP出现下面错误时, Permission denied. Passive mode refused. Permission denied. Passive mode refuse ...
- DVWA sqli
level low 可以看到查询请求为 http://192.168.31.xxx/vulnerabilities/sqli/?id=1&Submit=Submit# ##### id 改为 ...
- crontab采坑总结
目录 crontab环境变量 脚本缺少执行权限 crontab是Linux平台实现定时任务的服务工具,通常情况下该服务会预装在发行版中,直接使用即可. 关于crontab的详细用法参考:https:/ ...
- Unity学习笔记--数据持久化Json
JSON相关 json是国际通用语言,可以跨平台(游戏,软件,网页,不同OS)使用, json语法较为简单,使用更广泛.json使用键值对来存储. 认识json文件 //注意字典类型存储时,键是以st ...
- 正则函数及面向对象开发初识---day19
1.正则函数 # ### 正则函数 import re #search 通过正则匹配出第一个对象返回,通过group取出对象中的值 strvar = "1+2 3*4" obj = ...
- 【LeetCode数组#4滑动窗口】长度最小的子数组+子数组最大平均数I
长度最小的子数组 力扣题目链接(opens new window) 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度.如果不存 ...
- C++ //count_if //按条件统计元素个数 //自定义和 内置
1 //按条件统计元素个数 2 //count_if 3 4 #include <iostream> 5 #include<string> 6 #include<vect ...