作者:bravo1988
链接:https://www.zhihu.com/question/317687988/answer/1715863550
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

大致介绍完Java对象内存结构后,我们再来解决一个新疑问:

为什么需要标记锁的状态呢?是否意味着synchronized锁有多种状态呢?

在JDK早期版本中,synchronized关键字的实现是直接基于重量级锁的。只要我们在代码中使用了synchronized,JVM就会向操作系统申请锁资源(不论当前是否真的是多线程环境),而向操作系统申请锁是比较耗费资源的,其中涉及到用户态和内核态的切换等,总之就是比较费事,且性能不高。

JDK为了解决JVM锁性能低下的问题,引入了ReentrantLock,它基于CAS+AQS,类似自旋锁。自旋的意思就是,在发生锁竞争的时候,未争取到锁的线程会在门外采取自旋的方式等待锁的释放,谁抢到谁执行。

自旋锁的好处是,不需要兴师动众地切换到内核态申请操作系统的重量级锁,在JVM层面即可实现自旋等待。但世界上并没有百利而无一害的灵丹妙药,CAS自旋虽然避免了状态切换等复杂操作,却要耗费部分CPU资源,尤其当可预计上锁的时间较长且并发较高的情况下,会造成几百上千个线程同时自旋,极大增加CPU的负担。

synchronized毕竟JDK亲儿子,所以大概在JDK1.6或者更早期的版本,官方对synchronized做了优化,提出了“锁升级”的概念,把synchronized的锁划分为多个状态,也就是上图中提到的:

  • 无锁
  • 偏向锁
  • 轻量级锁(自旋锁)
  • 重量级锁

无锁就是一个Java对象刚new出来的状态。当这个对象第一次被一个线程访问时,该线程会把自己的线程id“贴到”它的头上(Mark Word中部分位数被修改),表示“你是我的”:

此时是不存在锁竞争的,所以并不会有什么阻塞或等待。

为什么要设计“偏向锁”这个状态呢?

大家回忆一下,项目中并发的场景真的这么多吗?并没有吧。大部分项目的大部分时候,某个变量都是单个线程在执行,此时直接向操作系统申请重量级锁显然没有必要,因为根本不会发生线程安全问题。

而一旦发生锁竞争时,synchronized便会在一定条件下升级为轻量级锁,可以理解为一种自旋锁,具体自旋多少次以及何时放弃自旋,JDK也有一套相关的控制机制,大家可以自行了解。

同样是自旋,所以synchronized也会遇到ReentrantLock的问题:如果上锁时间长且自旋线程多,又该如何?

此时就会再次升级,变成传统意义上的重量级锁,本质上操作系统会维护一个队列,用空间换时间,避免多个线程同时自旋等待耗费CPU性能,等到上一个线程结束时唤醒等待的线程参与新一轮的锁竞争即可。

synchronized案例

让我们一起来看几个案例,加深对synchronized的理解。

  • 同一个类中的synchronized method m1和method m2互斥吗?

t1线程执行m1方法时要去读this对象锁,但是t2线程并不需要读锁,两者各管各的,没有交集(不共用一把锁)

  • 同一个类中synchronized method m1中可以调用synchronized method m2吗?

synchronized是可重入锁,可以粗浅地理解为同一个线程在已经持有该锁的情况下,可以再次获取锁,并且会在某个状态量上做+1操作(ReentrantLock也支持重入)

  • 子类同步方法synchronized method m可以调用父类的synchronized method m吗?

子类对象初始化前,会调用父类构造方法,在结构上相当于包裹了一个父类对象,用的都是this锁对象

  • 静态同步方法和非静态同步方法互斥吗?

各玩各的,不是同一把锁,谈不上互斥

需要更多教程,微信扫码即可

synchronized与锁升级相关推荐

  1. 第十二章:synchronized与锁升级

    相关面试题 锁优化背景 Synchronized 锁性能变化 jdk5 以前 复习:为什么任意一个对象都能成为锁? jdk6 之后 synchronized的种类以及锁升级流程 锁升级流程 无锁 偏向 ...

  2. 大话Synchronized及锁升级

    作者:jack_xu juejin.im/post/5e898b8fe51d4546cd2fda30 为什么要用Synchronized 这个问题很简单,首先我们来看下面这个代码 开10000个线程, ...

  3. 简述Synchronized以及锁升级

  4. 12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁

    小陈:呼叫老王...... 老王:来了来了,小陈你准备好了吗?今天我们来讲synchronized的锁重入.锁优化.和锁升级的原理 小陈:早就准备好了,我现在都等不及了 老王:那就好,那我们废话不多说 ...

  5. Synchronized关键字和锁升级

    一.Synchronized 对于多线程不安全(当数据共享(临界资源),而多线程同时访问并改变该数据时,就会不安全),JAVA提供的锁有两个,一个是synchronized关键字,另外一个就是lock ...

  6. synchronized 底层如何实现?什么是锁升级、降级?

    synchronized 底层如何实现?什么是锁升级.降级? synchronized 代码块是由一对 monitorenter/monitorexit 指令实现的,Monitor 对象是同步的基本实 ...

  7. 存储过程没有执行完后没有释放锁_面试必问---synchronized实现原理及锁升级过程你懂吗?...

    synchronized实现原理及锁升级过程 前言: synchronized是Java内置的机制,是JVM层面的,而Lock则是接口,是JDK层面的 尽管最初synchronized的性能效率比较差 ...

  8. 在c#中用mutex类实现线程的互斥_面试官经常问的synchronized实现原理和锁升级过程,你真的了解吗...

    本篇文章主要从字节码和JVM底层来分析synchronized实现原理和锁升级过程,其中涉及到了简单认识字节码.对象内部结构以及ObjectMonitor等知识点. 阅读本文之前,如果大家对synch ...

  9. synchronized锁升级_synchronized详解以及锁的膨胀升级过程

    点击上方"码之初"关注,···选择"设为星标" 与精品技术文章不期而遇 来源:www.cnblogs.com/cxiaocai/p/12189848.html ...

最新文章

  1. 精灵图 html为什么会变大,[html] 第128天 精灵图和base64如何选择呢?
  2. footer始终在页面最底部的方法(问题待检验)
  3. Kubernetes面试题超详细总结
  4. 中国学霸们被世界名校集体退学,原因竟然是……
  5. Promise处理前端异步事件
  6. matlab矩阵除以一个数字,matlab矩阵中每一行数除以一个数 | 学步园
  7. 99岁田家炳博士辞世!捐助300多所学校…
  8. Knative 驾驭篇:带你 '纵横驰骋' Knative 自动扩缩容实现
  9. Spring Boot Framework的关键组件和内部构造(自动装配、起步依赖、CLI、Actuator)
  10. linux如何看分配固定共享内存段,Linux共享内存的查看和删除
  11. ZJOI2007时态同步
  12. Illustrator 教程,如何在 Illustrator 中重新着色图稿?
  13. 智能优化算法:基于梯度的优化算法-附代码
  14. VS | 设置头文件包含目录(无法打开包括文件,No such file or directory的解决)
  15. 关于QQ热键在不知道的情况下找出热键组合的办法
  16. 感悟和体会数据结构和算法
  17. 我的物联网项目(二十四) 订单编号生成规则
  18. consistent equation
  19. 湖北省教育考试院湖北省人事考试网报名入口报名时间软考报名
  20. csdn各种积分规则

热门文章

  1. 真香无疑了!新iPhone抢断货,国内最受欢迎的颜色是它
  2. 三星官方回应“7nm EUV良率”:内容与事实完全不符
  3. 收到手机第二天就自燃?S10机主怒告三星 要求道歉并索赔1元
  4. 华为Mate30系列前面板曝光:双曲面刘海屏再获证实
  5. 甲骨文中国疯狂裁员 招聘网站上线“甲骨文人才专场”
  6. 苹果AirPower总是跳票的原因找到了?或因商标被抢注
  7. 软件测试基础课程学习笔记5---软件缺陷概述
  8. 计算机应用教程第9,计算机应用教程(第8版)第六章
  9. vant图标怎么显示不出来_Vant Icon 图标
  10. stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速