在JDK1.6以前,使用synchronized就只有一种方式即重量级锁,而在JDK1.6以后,引入了偏向锁,轻量级锁,重量级锁,来减少竞争带来的上下文切换。

锁升级主要依赖对象头中的Mark Word中的锁标志位和释放偏向锁标识位。

一般的synchronized同步锁升级步骤是:偏向锁 -> 轻量级锁 -> 重量级锁。

注意:锁只能升级,不能降级。

偏向锁

偏向锁,顾名思义是偏向某一个线程的锁,在该某个线程第一次成功锁时,会在对象头中存储所偏向的线程ID,如果下一次还是该线程获取锁,只需要在对象头Mark Word中去判断一下是否有偏向锁指向它的ID,大大减少了性能的消耗。

什么时候升级为轻量级锁呢?

当有另外一个线程竞争获取这个锁时,由于该锁已经是偏向锁,当发现对象头 Mark Word 中的线程 ID 不是自己的线程 ID,就会进行 CAS 操作获取锁,如果获取成功,直接替换 Mark Word 中的线程 ID 为自己的 ID,该锁会保持偏向锁状态;如果获取锁失败,代表当前锁有一定的竞争,偏向锁将升级为轻量级锁。

轻量级锁

轻量级锁是相对于重量级锁而言,轻量级锁不需要申请互斥量,只需要将Mark Word 中的部分字节CAS更新指向栈中锁记录的指针,如果更新成功,则轻量级锁获取成功,记录锁状态为轻量级锁;否则,说明已经有线程获取了轻量级锁,发生了锁竞争,轻量级锁开始自旋。

自旋锁与自适应自旋锁

自旋锁(包括自适应自旋锁)是轻量级锁在升级为重量级锁前做的最后一次挣扎。

在JDK1.6之前设置自旋锁为自旋超过十次,或者等待线程超过cpu核数的2分之一,锁升级为重量级锁;

在JDK1.6后优化为自适应的自旋锁,如果自旋超过一定次数,或者此时有第三个线程来竞争该锁时,锁升级为重量级锁。

重量级锁

重量级锁是如果多个线程同时竞争锁,只会有一个线程得到这把锁,其他线程获取锁失败,不会和轻量级锁进行自旋等待锁被释放,而是直接阻塞没有获取成功的线程。

重量级锁需要操作系统对线程状态的切换,

当锁升级为重量级锁后,未抢到锁的线程都会被阻塞,进入阻塞队列。

总结

synchronized的执行过程:

  1. 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁
  2. 如果不是,则使用CAS将当前线程的ID替换Mard Word中的线程ID,如果成功则表示当前线程获得偏向锁,置偏向标志位1
  3. 如果失败,则说明发生竞争,撤销偏向锁,进而升级为轻量级锁。
  4. 当前线程使用CAS将对象头的Mark Word替换为锁记录指针,如果成功,当前线程获得锁
  5. 如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
  6. 如果自旋成功则依然处于轻量级状态。
  7. 如果自旋失败,则升级为重量级锁。

synchronized中锁是怎么升级的的更多相关文章

  1. 【转载】Java中的锁机制 synchronized & 偏向锁 & 轻量级锁 & 重量级锁 & 各自优缺点及场景 & AtomicReference

    参考文章: http://blog.csdn.net/chen77716/article/details/6618779 目前在Java中存在两种锁机制:synchronized和Lock,Lock接 ...

  2. java架构之路(多线程)synchronized详解以及锁的膨胀升级过程

    上几次博客,我们把volatile基本都说完了,剩下的还有我们的synchronized,还有我们的AQS,这次博客我来说一下synchronized的使用和原理. synchronized是jvm内 ...

  3. synchronized的锁升级/锁膨胀

    偏向锁 偏向第一个拿到锁的线程. 即第一个拿到锁的线程,锁会在对象头 Mark Word 中通过 CAS 记录该线程 ID,该线程以后每次拿锁时都不需要进行 CAS(指轻量级锁). 如果该线程正在执行 ...

  4. [多线程] 线程中的synchronized关键字锁

    为什么要用锁? 在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实 ...

  5. Synchronized偏向锁和轻量级锁的升级

    原文:https://blog.csdn.net/tongdanping/article/details/79647337 锁的优化1.锁升级锁的4中状态:无锁状态.偏向锁状态.轻量级锁状态.重量级锁 ...

  6. 并发王者课-青铜7:顺藤摸瓜-如何从synchronized中的锁认识Monitor

    在前面的文章中,我们已经体验过synchronized的用法,并对锁的概念和原理做了简单的介绍.然而,你可能已经察觉到,有一个概念似乎总是和synchronized.锁这两个概念如影相随,很多人也比较 ...

  7. synchronized、锁、多线程同步的原理是咋样

    先综述个结论: 一般说的synchronized用来做多线程同步功能,其实synchronized只是提供多线程互斥,而对象的wait()和notify()方法才提供线程的同步功能. 一般说synch ...

  8. Java-synchronized 中锁的状态及其转换

    synchronized 锁的优化过程:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 一.不同锁对象的状态表示(需要了解 Java 对象头) https://wiki.open ...

  9. synchronized互斥锁实例解析

    目录 synchronized互斥锁实例解析 1.互斥锁基础使用:防止多个线程同时访问对象的synchronized方法. 1.1.多个线程调用同一个方法 1.2.多个线程多个锁,升级为类锁 2.线程 ...

随机推荐

  1. Atlas 分表功能

    目录 分表原因 分表方式 Atlas 分表 分表思路 配置 Atlas 创建原表 创建分表 数据测试 分表原因 1.数据过多,访问缓慢 2.创建索引时重新排序,创建缓慢,并且占用大量的磁盘空间 分表方 ...

  2. 杭电多校HDU 6599 I Love Palindrome String (回文树)题解

    题意: 定义一个串为\(super\)回文串为: \(\bullet\) 串s为主串str的一个子串,即\(s = str_lstr_{l + 1} \cdots str_r\) \(\bullet\ ...

  3. ysoserial-URLDNS学习

    简述 ysoserial很强大,花时间好好研究研究其中的利用链对于了解java语言的一些特性很有帮助,也方便打好学习java安全的基础,刚学反序列化时就分析过commoncollections,但是是 ...

  4. python文件持久化存储

    文件持久化存储 目录 文件持久化存储 脑图 文件的操作 with 语句 OS模块 json模块 存储为Excel文件 脑图 文件的操作 import os import platform # 1. 获 ...

  5. canvas画布基本知识点总结

    HTML5的canvas元素使用JavaScript画图: <canvas width="600" height="400"> </canva ...

  6. MOOC学习成果认证及对高等教育变革路径的影响

    MOOC是网络开放教育创新发展的产物,也是备受人们欢迎的网络学习途径.当前制约MOOC能否可持续深入发展的问题聚焦于MOOC学习成果能否得到合理的认证.MOOC学习成果认证分为非学分认证和学分认证.M ...

  7. TypeScript callback Object params

    TypeScript callback Object params 回调函数 对象 参数 const func = (options = {}) => { // do somthing retu ...

  8. docthis & VS code

    docthis & VS code JSDoc 3 http://usejsdoc.org/ http://usejsdoc.org/about-getting-started.html ht ...

  9. js replace all

    js replace all https://stackoverflow.com/questions/1144783/how-can-i-replace-all-occurrences-of-a-st ...

  10. WEB 面向开发者的结构化数据

    通常用于google搜索 See also: video 探索搜索库