java并发编程汇总3:synchronized、volatile、java对象结构、CAS

参考之前写的博客:

Java 并发编程(三):synchronized、volatile 详解
java对象结构

梳理一下整体结构:

1、synchronized关键字(锁:阻塞式、重量级、对象锁机制monitor;

2、CAS(锁:乐观、非阻塞、无锁)、以及存在的三个问题;

3、Java对象头结构:

  • 包含:MarkWordKlass Word、数组长度、对象体、对齐字;
  • Klass Word:JVM通过这个指针确定对象是哪个类的实例
  • MarkWord中锁的四种状态:无锁01、偏向锁01、轻量级锁00、重量级锁10;
  • 偏向锁:不需要进行CAS操作来加锁和解锁;
  • 轻量级锁:使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁;
  • 锁的升级过程:
  1. 初期锁对象刚创建时,还没有任何线程来竞争,对象的Mark Word是下图的第一种情形,这偏向锁标识位是0,锁状态01,说明该对象处于无锁状态(无线程竞争它)。
  2. 当有一个线程来竞争锁时,先用偏向锁,表示锁对象偏爱这个线程,这个线程要执行这个锁关联的任何代码,不需要再做任何检查和切换,这种竞争不激烈的情况下(准确的说:只有一个线程、没有竞争的情况下),效率非常高。这时Mark Word会记录自己偏爱的线程的ID,把该线程当做自己的熟人。如下图第二种情形。
  3. 当有两个线程开始竞争这个锁对象,情况发生变化了,不再是偏向(独占)锁了,锁会升级为轻量级锁,两个线程公平竞争,哪个线程先占有锁对象并执行代码,锁对象的Mark Word就执行哪个线程的栈帧中的锁记录。如下图第三种情形。
  4. 如果竞争的这个锁对象的线程更多,导致了更多的切换和等待,JVM会把该锁对象的锁升级为重量级锁,这个就叫做同步锁,这个锁对象Mark Word再次发生变化,会指向一个监视器对象,这个监视器对象用集合的形式,来登记和管理排队的线程。如下图第四种情形。

4、volatile关键字(锁:非阻塞、轻量级):

  • 涉及JMM、happens-before,三大性质:原子、可见、一致;
  • volatile的内存语义实现:内存屏障(4种类型);
  • volatile写是在前面和后面分别插入内存屏障,而volatile读操作是在后面插入两个内存屏障

猜你喜欢

转载自blog.csdn.net/ScorpC/article/details/113822708