当前位置: 首页 > article >正文

JUC-synchronized 知多少

synchronized 底层是通过 monitor 锁实现的,每个对象都会关联一个 monitor

monitor的主要组成部分

  • owner 指针:指向持有对象锁的线程。初始时 owner 未空
  • 计数器:初始值为 0,当线程加锁成功时,计数器 +1,线程释放锁时 -1
  • waitSet: 当调用了 wait方法时,线程会被加入到 waitSet中,当调用 notify, notifyAll唤醒线程后,线程会被加入到 entryList
  • entryList: 未获取到锁的线程会被加入到 entryList中

对象头

对象头中的 MarkWord 字段会保留monitor的引用,锁的标志。

锁标记位偏移标记位
010无锁
011偏向锁
00-轻量级锁
10-重量级锁
11-GC 标记

synchronized 加锁过程

当线程执行到被 synchronized 修饰的同步代码块时:

通过对象头中的 monitor 对象的引用,找到对应的 monitor锁对象,如果 owner 引用为空,该线程就会获取锁成功,owner指向该 线程,计数器加 1, 否则加锁失败。

synchronized 支持重入锁

同一个线程,没获取一次锁,计数器就加一,没释放一次锁,计数器减一,当计数器为 0 时,线程释放掉全部的锁,owner 重新被设置为 null。

synchronized 锁升级过程

  1. 无锁:锁对象被创建时,处于无锁状态

  2. 偏向锁:此时如果有一个线程来获取锁,就会升级为偏向锁,这样就可以保证当该线程下次再来获取锁时,就避免了加锁和解锁的操作,减少系统开销

  3. 轻量级锁:如果此时又来了一个线程来竞争锁,偏向锁升级为轻量级锁,未获取到锁的线程会自旋尝试获取锁,而不是阻塞,可以减少不必要的上下文切换

  4. 重量级锁:如果未获取到锁的线程自旋达到一定次数,或者又有别的线程来竞争锁,此时轻量级锁会升级为重量级锁

    状态条件意义
    无锁新建锁对象
    无锁 → 偏向锁只有一个线程来获取锁避免同一个线程再次进入同步代码块加锁和解锁的过程
    偏向锁 → 轻量级锁又来一个线程来获取锁未获取到线程的锁尝试自旋获取锁,而不是阻塞,减少上下文切换
    轻量级锁 → 重量级锁自旋获取锁失败,或有多个线程来竞争锁

http://www.kler.cn/news/339288.html

相关文章:

  • 灵动微高集成度电机MCU单片机
  • Windows无需管理员权限,命令轻松修改IP和DNS
  • EtherCAT学习笔记
  • 【Qt】窗口预览(1)—— 菜单栏
  • std::future概念和使用方法
  • Arduino UNO R3自学笔记23 之 Arduino如何使用4511控制数码管?
  • 最佳实践(1)
  • `pandas` 库提供了一个非常方便的方法将 DataFrame 转换为字典
  • 2024年最新版本神马TV8.5影视APP源码 293TV影视点播系统源码搭建教程 神马TV8.2加强版反编译教程 保姆级小白可搭建 完整版本视频教程
  • 揭开DNA实验室装修的秘密:水电管道设计的关键要点
  • C# 自适应屏幕分辨率
  • Python从入门到高手4.3节-掌握跳转控制语句
  • 02_InFluxDb
  • MHA携手Atlas:打造高效读写分离解决方案,引领数据库性能飞跃
  • C++学习笔记----8、掌握类与对象(四)---- 不同类型的数据成员(2)
  • Sym-NCO:利用对称性进行神经组合优化
  • 餐饮生存战:平价消费时代,别盲目卷低价
  • 2.4Mybatis——缓存机制
  • 算法:前缀和算法模版
  • [笔记] 仿射变换性质的代数证明