欢迎光临散文网 会员登陆 & 注册

【Java并发】月薪30K必须知道的Java锁机制

2022-10-21 04:04 作者:裹魁钺  | 我要投稿


00:52


并发环境下,多个线程会对同一个资源进行争抢,可能导致数据不一致的问题

编程语言引入锁机制,对资源进行锁定


01:08





01:58


“锁”是一个抽象概念


02:02


锁放在对象头中。

锁中记录了当前对象被哪个线程所占用


02:17


Java对象:

对象头、实例数据、对齐填充字节


02:51


对象头存放对象的运行时信息

对象头包含

  1. MarkWork
  2. 存储和当前对象运行时状态有关的数据
  3. hashcode
  4. 锁状态标志
  5. 指向锁记录的指针
  6. 偏向锁id
  7. 锁标志位
  8. ClassPoint
  9. 指针
  10. 指向当前对象类型所在方法去中断类型数据




03:21


32bit


03:48



无锁、偏向锁、轻量级锁、重量级锁




04:07


synchronized 编译后生成两个字节码指令

  • monitorenter
  • monitorexit

依赖此二指令实现线程同步


04:26




05:19


javac 编译 javac *.java

javap 反编译 javap -c *.class

得到可读性较高的字节码


05:42


synchronized同步机制围绕Monitor展开




06:45


monitor是依赖操作系统的mutex lock来实现的

Java系统是对操作系统线程的映射

每当挂起或者唤醒,都需要切换操作系统的内核态——这是“重量级的操作”,对程序性能有严重影响。


07:20




07:33





07:51



synchronized是如何优化的

(锁)四种状态是如何变化的?



07:59




08:32





09:08


“偏向”:monitor偏向于对指定的线程交出锁



09:38


MarkWord中,当锁标志位是01时,判断倒数第3个bit是否为1,

  • 若为0,则非偏向锁。
  • 若为1,则当前对象的锁状态为偏向锁
  • 若为偏向锁,再读取MarkWord前23bit,即对象的线程ID,根据线程ID,判断是不是“老顾客”
  • 若是: 则直接调用对象
  • 若否:即多个对象同时竞争,则偏向锁将升级为轻量锁。



10:10


当锁状态为“偏向锁”时,通过MarkWord的线程ID来找到占有该锁的线程。

当锁状态升级为轻量级锁时,如何判断你线程与锁的绑定关系


10:29


MarkWord前30bit改为指向栈中锁记录的指针



10:38


线程判别所标志位是否为00轻量级锁

若是,线程在自己的虚拟机栈中开辟Lock Record的空间

(Lock Record 是线程私有的)


11:04


Lock Record 存放对象的

  • MarkWord副本
  • owner指针

“线程通过CAS尝试获取锁,一旦获得将复制对象头中的MarkWord道Lock Record中,并将LockRecord的owner指针指向该对象”




另一方面

对象的前30bit,生成一个指针,指向虚拟机栈中的Lock Record

如此边双向关联了 markwork <-> 线程虚拟机栈

“实现了线程和对象锁的绑定(他们互相知道了对方的存在)”

此时该对象已被锁定,获取道对象的线程就可以去执行一些任务


此时如果有其他线程也想获取这个对象

其他的线程将会“自旋”等待



11:51


“自旋”:一种轮询,线程不断地自我循环,检查目标对象的锁有没有被释放

  • 若释放,获取之
  • 若未释放,则进行下一轮循环


12:04


若对象锁很快被释放,相比OS挂起,自旋不需要进行系统中断和现场恢复,效率更高。

自旋:相当于CPU在空转。长时间自旋,会浪费CPU资源。


12:21



自适应自旋:自旋的实践不固定,

由两个条件决定:

  1. 上一次在同一个锁上的自旋时间
  2. 锁状态

“在同一个锁上,当前正在自选等待的线程,刚刚已经成功获得过锁,但是锁目前被其他线程占用着,那么虚拟机就会认为这次自旋也很有可能会再次成功,进而它将允许更长的自选时间”



12:49


一旦自旋等待的线程数量超过1个,那么轻量级锁将会升级为重量级锁

若对象锁状态被标记为重量级锁,则需要通过Monitor来对线程进行控制,此时将会完全锁定资源,对线程的管控最为严格

(升级道重量锁,等于变回了OS Mutex)



13:14


锁、Java锁、对象头、MarkWord

synchronized -> monitor -> mutex lock

无锁->偏向->轻量->重量






【Java并发】月薪30K必须知道的Java锁机制的评论 (共 条)

分享到微博请遵守国家法律