Synchronized

325 阅读2分钟

1 使用场景

  • 锁静态方法 (锁的对象是Class对象)
  • 锁实例方法 (锁的对象是类实例)
  • 锁方法体 (手动传入一个锁对象:this/Class/其他实例)

2 最基本的Synchronized锁原理

字节码上解释为通过 Monitor Enter 获取锁对象的Monitor监视器;通过Monitor Exit释放锁。

  • Monitor Enter
  • Monitor Exit

zis

3 Synchronized 在JMM上的含义

使用Synchronized关键字的作用,能为我们做的事情

3-1 Happens before 规则

  • 释放锁 HB 加锁
  • 上一个线程执行的临界区代码 HB 下一个线程的临界区代码

3-2 内存语义

  • 获取锁的时候,从主内存中进行获取数据
  • 释放锁的时候,将数据刷新到主内存
  • 隐含通信语义:上一个线程向下一个线程传递数据,隐式通信

4 Synchronized 优化

4-1 优化原因

  • 重量级Synchronized实现时将没有获取锁的对象放入阻塞队列中进入了休眠,放弃CPU执行权,从而导致上下文切换和线程的唤醒挂起很耗时,所以Synchronized的效率不高。

4-2 优化基础

  • Java对象头,锁的优化过程主要通过Mark Word的

  • Mark Word 里面的数据

4-3 优化过程

锁的升级过程:无锁状态 --> 偏向锁 --> 轻量级锁 --> 重量级锁

根据锁的竞争情况逐步进行升级,不能降级

4-4 偏向锁

目的:锁大多数情况是由一个线程获取,为了让同一个线程获取锁代价低,引入偏向锁,偏向某个线程,即锁很多情况下是不处于竞争状态的。

JVM参数:-XX:BiasedLockingStartupDelay=0

  • 偏向锁加锁

当前为偏向锁,通过CAS操作设置当前的偏向线程

  • 偏向锁的释放

当锁出现竞争的时候,就会去尝试释放锁资源

4-5 轻量级锁

4-6 各种锁之间的对比

参考

juejin.cn/post/684490…

juejin.cn/post/684490…