CAS:
Compare and Swap,即比较再交换。
jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。
CAS算法理解
对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做.
查看对象在内存中的布局:
引入依赖
<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.10</version> </dependency>
对象在内存中的布共分为四部分:
对象在内存中的布共分为四部分:
- Markword:主要存储锁的信息和GC的信息,占8个字节
- 类型指针class pointer :指向这个类在内存中的Class对象,占4个字节
- 实例数据 instance data : 这个类中实例对象所占的内存,如果int a 则占4个字节,如果时long b,则占8个字节
- 对齐padding:如果前边几个加起来的字节数不是8的整数倍,则填充补齐
所以Object o = new Object();在内存中共占用8+4+0+4共16个字节
锁的升级:锁的信息记录在markword中.
- Object o = new Object();在对象刚刚被new出来时,没有加任何锁.用markdown中最低三位代表锁状态,其中一位是偏向锁位,两位是锁标志位
- 此时线程A访问该对象,因为A是第一个访问该对象的线程,此时没有其它线程竞争,o的markword的前54位指向了当前线程,此时为偏向锁.
- 当线程A添加了偏向锁之后,线程B也来访问o对象,A,B两个线程竞争.这两个线程分别在各自的线程栈中生成一个Lock Record,以CAS的方式对o竞争加锁,假设A成功,则o的markword指向线程A的Lock Record,线程B处于自旋状态.此时o上添加的是轻量级锁也叫自旋锁,也叫无锁.
- 当线程B自选次数超过10次,则向操作系统内核态申请重量级锁资源