CAS理解
概述
- CAS是多线程的一个基础,可以先了解一下CAS
- CAS引入的条件就是:在不加锁的情况下,实现多线程对同一个数据的修改是线程安全的
- 可以简单理解成不加synchronized却可以实现线程安全
-
代码示例
图解
ABA问题
比较E和N的时候,E改了2次,又改回之前的值了
解决方案:除了比较值,再加一个字段,然后同时比较这个值和新加的这个字段 增加加版本号,每次改的时候版本+1
增加boolean字段判断,类java.util.concurrent.atomic.AtomicStampedReference
CAS本质实现
同synchronize和volite的实现是一样的
JVM的实现我们就采用HostSpot(官方的)
JOL(java object layout)来理解CAS
如果关闭了类型指针压缩,markword 8个 class pointer8个 instance data0个 对齐0个—->总共16个字节
一个自定义对象在堆里面占据了几个字节呢?
加锁以后的信息存放在哪里呢?
jdk1.8 锁的升级过程(也可以看做对象的markword里记录了啥呢?)刚new出来的对象
- 偏向锁
- 轻量级锁(无锁,自旋锁)
- 重量级锁
锁升级的图解
老师总结
锁降级
只有GC的时候会发生,一般可以认为没有意义,简单认为锁降级不存在
锁消除
这个StringBuffer对象是线程安全的,里面的操作用synchronize修饰的,但是这个方法存在于一个方法里面,是局部变量(栈私有),不涉及线程安全问题,怎么分析线程安全呢?通过分析这个对象是否跑出了这个方法(并非逃逸分析),因此jvm会帮我们自动消除StringBuffer对象内部的锁,提升效率
锁粗化
jvm会把append方法内的锁,放到while外面,本来要加锁解锁100次,现在只要1次