原理

众所周知 synchronized 关键字是解决并发问题常用解决方案,有以下三种使用方式:

  • 同步普通方法,锁的是当前对象。
  • 同步静态方法,锁的是当前 Class 对象。
  • 同步块,锁的是 () 中的对象。

实现原理: JVM 是通过进入、退出对象监视器( Monitor )来实现对方法、同步块的同步的。
具体实现是在编译之后在同步方法调用前加入一个 monitor.enter 指令,在退出方法和异常处插入 monitor.exit 的指令。
其本质就是对一个对象监视器( Monitor )进行获取,而这个获取过程具有排他性从而达到了同一时刻只能一个线程访问的目的。
而对于没有获取到锁的线程将会阻塞到方法入口处,直到获取锁的线程 monitor.exit 之后才能尝试继续获取锁。

通过一段代码来演示:

使用 javap -c Synchronize 可以查看编译之后的具体信息。

这里插入一下,推荐一个在IDEA中快速使用Javap的方法。

步骤

使用方法

添加之后选中类然后运行,就会把字节码打印到控制台,非常方便

锁优化

synchronized 很多都称之为重量锁,JDK1.6 中对 synchronized 进行了各种优化,为了能减少获取和释放锁带来的消耗引入了偏向锁轻量锁

轻量锁

当代码进入同步块时,如果同步对象为无锁状态时,当前线程会在栈帧中创建一个锁记录(Lock Record)区域,同时将锁对象的对象头中 Mark Word 拷贝到锁记录中,再尝试使用 CASMark Word 更新为指向锁记录的指针。

如果更新成功,当前线程就获得了锁。

如果更新失败 JVM 会先检查锁对象的 Mark Word 是否指向当前线程的锁记录。

如果是则说明当前线程拥有锁对象的锁,可以直接进入同步块。

不是则说明有其他线程抢占了锁,如果存在多个线程同时竞争一把锁,轻量锁就会膨胀为重量锁

解锁

轻量锁的解锁过程也是利用 CAS 来实现的,会尝试锁记录替换回锁对象的 Mark Word 。如果替换成功则说明整个同步操作完成,失败则说明有其他线程尝试获取锁,这时就会唤醒被挂起的线程(此时已经膨胀为重量锁)

轻量锁能提升性能的原因是:

认为大多数锁在整个同步周期都不存在竞争,所以使用 CAS 比使用互斥开销更少。但如果锁竞争激烈,轻量锁就不但有互斥的开销,还有 CAS 的开销,甚至比重量锁更慢。

偏向锁

为了进一步的降低获取锁的代价,JDK1.6 之后还引入了偏向锁。

偏向锁的特征是:锁不存在多线程竞争,并且应由一个线程多次获得锁。

当线程访问同步块时,会使用 CAS 将线程 ID 更新到锁对象的 Mark Word 中,如果更新成功则获得偏向锁,并且之后每次进入这个对象锁相关的同步块时都不需要再次获取锁了。

释放锁

当有另外一个线程获取这个锁时,持有偏向锁的线程就会释放锁,释放时会等待全局安全点(这一时刻没有字节码运行),接着会暂停拥有偏向锁的线程,根据锁对象目前是否被锁来判定将对象头中的 Mark Word 设置为无锁或者是轻量锁状态。

偏向锁可以提高带有同步却没有竞争的程序性能,但如果程序中大多数锁都存在竞争时,那偏向锁就起不到太大作用。可以使用 -XX:-UseBiasedLocking 来关闭偏向锁,并默认进入轻量锁。

其他优化

适应性自旋

在使用 CAS 时,如果操作失败,CAS 会自旋再次尝试。由于自旋是需要消耗 CPU 资源的,所以如果长期自旋就白白浪费了 CPUJDK1.6加入了适应性自旋:

如果某个锁自旋很少成功获得,那么下一次就会减少自旋。

原文地址:https://crossoverjie.top/JCSprout/#/thread/Synchronize

转载于:https://www.cnblogs.com/Scramblecode/p/11170092.html

一文搞懂synchronized原理相关推荐

  1. 一文搞懂Synchronized同步锁的作用范围

    文章目录 类锁 修饰静态方法 修饰代码块 实战演练 对象锁 修饰普通方法 修饰代码块 实战演练 分析   我们对一个方法 增加Synchronized关键字后,当多个线程访问该方法时,整个执行过程会变 ...

  2. 一文搞懂 ThreadLocal 原理

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 武培轩 来源 | 公众号「武培轩」 当多线程访 ...

  3. IM的扫码登录功能如何实现?一文搞懂主流的扫码登录技术原理

    本文引用了3位作者"精品唯居"."  Yangfan2016"." MrYun"的部分文章内容,一并感谢. 1.引言 扫码登录这个功能,最早 ...

  4. 一文搞懂 Cocos Creator 3.0 坐标转换原理

    一文搞懂 Cocos Creator 3.0 坐标转换原理 屏幕坐标 UI 触点坐标 UI 多分辨率适配方案 UI 触点获取 不同坐标之间的转换 屏幕坐标与 3D 节点世界坐标互转 3D 节点之间的坐 ...

  5. 一文搞懂主流的扫码登录技术原理(附源码)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 1.引言 扫码登录这个功能,最早应该是微信的PC端开始搞,虽然有点反人类的功能(不扫码也没别的方式登录),但不得不说还是很酷的. 下面这张 ...

  6. 一文搞懂HMM(隐马尔可夫模型)-Viterbi algorithm

    ***一文搞懂HMM(隐马尔可夫模型)*** 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序, ...

  7. 一文搞懂 Cocos Creator 3.x 坐标转换!建议收藏

    Cocos Creator 3.x 如何将世界坐标转屏幕坐标?Creator 3D 怎么将 3D 坐标转化到 Canvas 上面?触摸的屏幕坐标如何转世界坐标?怎么把 Canvas 下的节点坐标转换为 ...

  8. 一文搞懂指标采集利器 Telegraf

    作者| 姜闻名 来源|尔达 Erda 公众号 ​ 导读:为了让大家更好的了解 MSP 中 APM 系统的设计实现,我们决定编写一个<详聊微服务观测>系列文章,深入 APM 系统的产品.架构 ...

  9. 一文搞懂k近邻(k-NN)算法(一)

    原文链接 一文搞懂k近邻(k-NN)算法(一) 前几天和德川一起在学习会上讲解了k-NN算法,这里进行总结一下,力争用最 通俗的语言讲解以便更多同学的理解. 本文目录如下: 1.k近邻算法的基本概念, ...

最新文章

  1. Spring对JNDI的支持方法
  2. 红旗系统linux忘了开机密码,红旗Linux6.0中忘记了root密码
  3. Dungeon Master——BFS
  4. VM安装CentOS6.8虚拟机
  5. SQL注入学习资料总结
  6. windows文本转语音 通过java 调用python 生成exe可执行文件一条龙
  7. Android学习之NDK环境的配置
  8. centos vmware centos6.6 64位 kvm虚拟化安装配置 第四十二节课
  9. Swift类属性 static
  10. 同一程序在不同版本的framework下控件中英文显示的问题
  11. 数字转换大写英文字母
  12. 老子文化主题公园将在洛阳落户
  13. Excel根据表格内容批量导入指定图片到单元格
  14. python大数据好不好学_大数据好学吗?想转行大数据??
  15. 计算机网络 P2P应用
  16. Office Web App
  17. 采用分众分区发行,把电影带到更多人手里
  18. css多边形制作简历小标题二级标题
  19. 10年,知乎为何依旧“赚钱难”?
  20. Ajax深度学习【详细整理黑马视频】

热门文章

  1. shiro执行多个过滤器_Shiro 实战(四) - 过滤器机制
  2. linux查看u盘的分区,在Linux下访问windows分区以及U盘
  3. 事务和锁机制是什么关系
  4. 安装完MySQL后启动报错_MySQL数据库之mysql编译安装完成后,启动时报错The server quit without updating PID file...
  5. 代码逻辑分析_双十一模块 79.34% 的代码是怎样智能生成的
  6. python 调用 .netcore api_浅谈Python调用XBee的API来进行通讯
  7. epoll原理_如果这篇文章说不清epoll的本质,那就过来掐死我吧! (1)
  8. 量化投资拥有光明的未来
  9. 1. 吴恩达机器学习课程-作业1-线性回归
  10. 通过高速计算机网络和多媒体,全国2014.10办公自动化原理及应用试题