JDK1.6之前的synchronized是重量级锁,其锁的获得和释放会带来较大的性能消耗。在JDK1.6中,为了锁带来的性能消耗,引入了偏向锁和轻量级锁,并精心设计了锁的膨胀策略。

轻量级锁是在无竞争的情况下使用CAS操作消除同步使用的互斥量,而偏向锁是在无竞争的情况下把整个同步操作都消除掉,连CAS操作都不做。

关于对象头和其中的Mark Word的知识,不了解的自行补充,这里只放两张图

32位虚拟机下的Mark Word存储结构

偏向锁

在Mark Word中,有一个1bit的偏向模式标记,如果是1,表示对象是在偏向模式,如果是0,表示对象不是偏向模式。当对象刚创建时,处于默认的未锁定状态,在此状态中锁标志位=01偏向模式=0。当锁对象第一次被线程获取的时候,虚拟机会将其对象头中Mark Word设置为锁标志位=01偏向模式=1,表示进入偏向模式。同时使用CAS操作把得到这个锁的线程的ID记录在锁对象的Mark Word中。如果CAS成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再直接进行任何同步操作(例如加锁、解锁及对Mark Word的更新操作等),只需判断对象是否处于偏向锁状态且Mark Word中的线程ID是否是自己,如果是就直接进入。

偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试获得这个对象的锁时,持有这个对象偏向锁的线程才会释放锁。这时候虚拟机就要干活了,它首先根据对象目前是否处于被锁定状态决定是否撤销偏向(偏向模式=0),撤销后将标志位恢复到未锁定或轻量级锁定状态。

轻量级锁

在代码进入同步块的时候,如果同步对象没有被锁定(锁标志=01),虚拟机首先在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝。然后,虚拟机将使用CAS操作尝试把Mark Word更新为指向当前线程锁记录的指针,如果成功了,即代表该线程拥有了这个对象的锁,并将对象头中的锁标志设为“00”,表示此对象处于轻量级锁定状态。如果CAS失败,说明对象已经被锁了,那就要继续判断锁这个对象的是谁,如果是当前线程锁的(即Mark Word中的指针指向当前线程的栈帧),那就直接进入同步代码块,如果是别的对象锁的,说明这个对象的锁被其他线程抢占了,此时轻量级锁将不再有效,会膨胀为重量级锁。膨胀为重量级锁后Mark Word中存储的是指向系统互斥量的指针,后面等待锁的线程必须进入阻塞状态。

重量级锁

图片出处

对象头会关联到一个monitor对象,即监视器对象。此外synchronized关键字经过Javac编译后,会在同步块的前后分别形成monitorenter和monitorexit这个两个字节码指令。下面来看一下synchronized的执行过程:

  • 假设此时锁对象没有被锁定,当线程进入同步块的时候,遇到monitorenter,就会获取当前对象的一个所有权,这个时候monitor进入数为1,当前的这个线程就是这个monitor的owner。
  • 如果该线程已经是这个monitor的owner了,它再次进入,就会把进入数+1。(可重入性)
  • 当该线程执行完monitorexit,对应的进入数就-1,直到为0,才可以被其他线程持有。
  • 如果对象已经被锁定且owner不是该线程,该线程就进入阻塞状态。

为什么称之为重量级锁呢,关键就是“阻塞”这两个字。Java线程是映射到操作系统的原生内核线程之上的,如果要阻塞或唤醒一个线程,则需要操作系统来帮忙完成,这就要从用户态转换为内核态,这会耗费很多的处理器时间。尤其是对于很简单的同步块,状态转换消耗的时间甚至比用户代码本身的执行时间还要长,这是得不偿失的。

自旋锁

为了尽可能地避免阻塞线程,当线程申请锁而不可得时,不要立即进入阻塞状态,而是“稍等一会儿”。这时候该该线程不会释放CPU,执行一个忙循环(自旋)。自旋是有次数限制的,因为不能“占着CPU不计算”。如果在限制次数内成功获得了锁,就很舒服,因为避免了开销呀。相反,如果自旋超过了限制次数还没有获得锁,那只能乖乖进入阻塞状态了。这个限制次数,是可以通过参数修改的,默认是10次。

参考文章

死磕synchronized底层实现

面试题:synchronized的底层实现(偏向锁,轻量级锁,重量级锁)相关推荐

  1. synchronized锁升级之重量级锁

    目录 一.什么是重量级锁? 二.重量级锁的演示 三.重量级锁的原理 四.锁的优缺点对比 一.什么是重量级锁? 当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁. 这个重量级锁其实指的 ...

  2. 死磕Synchronized底层实现--偏向锁

    注:本篇很长,请找个舒适的姿势阅读. 本文为synchronized系列第二篇.主要内容为分析偏向锁的实现. 偏向锁的诞生背景和基本原理在上文中已经讲过了,强烈建议在有看过上篇文章的基础下阅读本文. ...

  3. yield方法释放锁吗_死磕Synchronized底层实现重量级锁

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:farmerjohngit 链接:https://github.com/farmer ...

  4. Synchronized锁升级:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁

    一. 概述 1. Synchronized锁升级的原因 用锁能够实现数据的安全性,但是会带来性能下降.无锁能够基于线程并行提升程序性能,但是会带来安全性下降. 2. Synchronized锁升级的过 ...

  5. Synchronize的底层优化(CAS,重量级锁,轻量级锁,偏向锁)

    Synchronize的底层优化(CAS,重量级锁,轻量级锁,偏向锁) Java 对象头 (重点) 对象头 对象头包含两部分: 运行时元数据(Mark Word)和类型指针(Klass Word) 运 ...

  6. Synchronized偏向锁、轻量级锁、重量级锁详解

    一.偏向锁加锁 1.通过CAS操作将当前线程的地址设置到锁对象的markword中.如果设置成功了,那么就是设置偏向锁成功了 2.在当前线程的栈贞中,创建锁记录(Lock Record),使这个锁记录 ...

  7. 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)

    接触过线程安全的同学想必都使用过synchronized这个关键字,在java同步代码快中,synchronized的使用方式无非有两个: 通过对一个对象进行加锁来实现同步,如下面代码. synchr ...

  8. synchronized的偏向锁、轻量级锁和重量级锁

    文章目录 Java对象头 偏向锁 批量重偏向 批量撤销 轻量级锁 重量级锁 Monitor 原理 Java对象头 普通对象 Mark Word在64 位虚拟机中的结构为 Mark Word后三(两)位 ...

  9. Synchronized的原理及自旋锁,偏向锁,轻量级锁,重量级锁的区别

    在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,Java S ...

  10. Java如何避免重量级锁,Java 中锁是如何一步步膨胀的(偏向锁、轻量级锁、重量级锁)...

    文章目录 重量级锁(Mutex Lock) 偏向锁(比较 ThreadID) 偏向锁获取过程 偏向锁的释放 轻量级锁(自旋) 轻量级锁的加锁过程 轻量级锁的释放 总结 重量级锁(Mutex Lock) ...

最新文章

  1. iOS: 零误差或极小误差的定时执行或延迟执行?
  2. iis5顺利安装诀窍
  3. 正确的 Git 提交记录和分支模型
  4. lsync+rsync 实时同步(ubuntu16.04系统)
  5. 【最新合集】编译原理习题(含答案)_20代码生成_MOOC慕课 哈工大 陈鄞
  6. 进程比线程更多资源_为什么我们不应该使用比我们需要更多的线程
  7. knn算法python代码_K-最近邻分类算法(KNN)及python实现
  8. python调用图灵api_python调用API实现智能回复机器人
  9. linux curl 命令(转)
  10. How to monitor mongodb replica set using prometheu
  11. AX 2012 键盘快捷键
  12. Dev-c++下载地址
  13. 将SpringBoot项目打包并部署到服务器
  14. NetApp存储方案及巡检命令
  15. html打印多了空白页,为什么打印Word文档会多打印出一空白页
  16. 51单片机最小系统板制作
  17. 扫描图片转换成文字怎么转
  18. 北京有两个百度,李彦宏只有一个陆奇
  19. SD卡简单介绍(个人笔记)杜绝垃圾堆里刨食
  20. 不同iPhone屏幕尺寸

热门文章

  1. 300多个城市加入信用城市建设,信用时代已来!
  2. 汇编程序:成绩分段统计
  3. 持续集成(4)工具对比
  4. Exchange 2013反垃圾邮件功能
  5. Codeforces Round #569 (Div. 2)A. Alex and a Rhombus
  6. javaweb实现教师和教室管理系统 java jsp sqlserver
  7. iOS_SN_深浅拷贝( 百度的)_转载
  8. C言语教程第三章: C言语挨次妄想开端(7)
  9. TextEditor
  10. 静态页面评论处理以及列表处理