【多线程】synchronized锁升级和优化

一.synchronized锁的特点

  • 乐观锁/悲观锁自适应(开始的时候是乐观锁,如果锁冲突变频繁,转变为悲观锁)
  • 轻量级锁/重量级锁自适应(开始的时候是轻量级锁,如果锁冲突变频繁,转变为重量级锁)
  • 自旋锁/挂起等待锁自适应(开始的时候是自旋锁,如果锁冲突变频繁,转变为挂起等待锁)
  • 不公平锁(随机唤醒)
  • 可重入锁
  • 不是读写锁

二.synchronized锁升级过程

由于synchronized锁具有锁升级/锁膨胀的能力,才具有自适应性

synchronized分为 无锁,偏向锁,轻量级锁,重量级锁的状态,会根据实际情况进行升级。

偏向锁

  • 偏向锁并没有真正的加锁,而是在对锁做了一个标记,如果没有另外的线程争夺这个资源,没有产生锁冲突,那么就不会真正的加锁,一旦有别的线程竞争这个锁,那么就会在别的线程获取之前,先获取到锁**(从偏向锁升级到轻量级锁)**
  • 有点类似于"懒汉模式",能不加锁,就不加锁 ,能晚加锁,就晚加锁
  • 在存在锁冲突的情况下,偏向锁没有提高效率,如果没有存在锁冲突,那么自旋锁就大大提高了效率

总结:非必要不加锁

轻量级锁

  • 轻量级锁通过自旋锁的方式来实现
  • 自旋锁最好使用在锁冲突不频繁的情况下,自旋操作会让cpu一直空转,浪费cpu资源
  • 轻量级锁出现在锁冲突并不严重的情况 ,synchronized锁内部也会对这个对象进行统计,统计有多少个线程参与竞争,如果竞争的线程太多,会从轻量级锁升级到重量级锁

重量级锁

  • 由于自旋操作浪费cpu资源,少数还可以接受,如果自旋的线程太多,非常浪费cpu资源,于是那些长时间拿不到锁资源的线程,不会继续自旋,而是会进入阻塞等待,让出cpu资源,等到这个锁资源被释放了,那么会随机唤醒一个阻塞线程
  • 重量级锁指的是内核提供的mutex锁

注意:像这样锁状态改变的过程,是单向的,只能锁升级,不能锁降级

三. synchronized锁的优化

锁消除

  • 锁消除是synchronized锁的一种优化策略,在程序编译的时候,JVM会对锁进行检查,判断这个线程是否需要加锁,倘若在不需要加锁的地方加锁,则会对锁进行消除,提高效率
  • 在多个线程中,只存在读操作,没有写操作,则会去掉其中的加锁操作
  • 单个线程中的读写操作,则也不需要加锁操作

这种锁消除的优化,非常保守, 只有那些一眼看上去不需要加锁的情况才会删除

锁粗化

  • 锁的粒度:synchronized代码块中代码数目的多少
  • 代码越多,锁的粒度越大,代码越少,锁的粒度越小

通常情况下,我们需要锁的粒度越细越好,这样有利于多个线程并发执行

  • 但是在一些特殊情况,需要锁的粒度粗一点
  • 加锁和解锁需要开销一定的资源,连续进行多次的加锁和解锁过程,更会消耗更多的资源

进行锁的粗化,通过减少加锁和解锁的次数,提高效率和减少锁竞争的开销


点赞的宝子今晚自动触发「躺赢锦鲤」buff!

相关推荐
benbenAItalk3 小时前
数字人口播视频的批量生产实践:素材规范、任务编排与质量验收
java·前端·音视频
sunshine22 girl3 小时前
Java学习二 基本语法2, 算术运算符
java·学习
2601_966949653 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
niucloud-admin3 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
2601_962885723 小时前
如何用 Python 扫描 A 股跳空缺口并统计缺口回补概率?
java·前端·python
滕州市燕猫虎计算机科技工作室个体工商户3 小时前
Java锁
java·开发语言
多加点辣也没关系4 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
菜鸟~noob2334 小时前
【电子战】 第09篇:阵列信号处理——波束形成、MVDR、MUSIC【含matlab代码】
开发语言·matlab·信号处理
ocean21034 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
零依赖极客4 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm