Java CAS

CAS(compare and swap):比较并且交换, 用于实现多线程同步的原子性,是一条CPU的并发原语;
CAS算法是Java的一种乐观锁,在原子性操作,自旋锁中都有使用;

原理是:在读取到主内存的数据后,保存该数据,然后对读取主内存的数据进行操作。在操作完毕后写回给主内存的时候,检查现在主内存的数去和开始读取的数据是否相同,如果相同,把操作后的数据写到主内存中,执行成功,否则执行失败,重新执行;

CAS的底层原理:unsafe+自旋锁

1.自旋锁:
2.unsafe类:java语言无法直接访问操作系统的底层,但是通过unsafe可以直接访问;
该类保证了CAS的原子性;调用Unsafe类中的CAS方法,JVM会帮助我们实现出CAS汇编指令,这是一条完全依赖于硬件的功能,通过它能够实现原子操作。由于CAS是一条系统原语,是由若干条指令组成,用于实现某个功能的过程,并且原语的执行必须是连续的,在执行过程中不允许被打断,也就是说CAS是一条CPU的原子指令,所以不会造成数据不一致的问题;
unsafe保证了compareAndSwapInt方法中Compare和Swap操作之间的原子性操作;

CAS底层的代码:

public final int incrementAndGet(){
	while(1){
		int current = get();
		int next = current + 1;
		if(compareAndSet(current, next)){
 			return next;
 		}
	}
}

CAS的缺点:

synchronized能够实现一致性,但是并发量下降;
CAS不加锁能够保证一致性和并发性,但是需要多次比较;
缺点:
1.如果CAS失败,会一直进行尝试和循环,如果长时间执行不成功,可能会给CPU带来很大的开销。
2.而且对于一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作;但是对于多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以使用锁来保证原子性;
3.会面临ABA的问题; 

CAS的ABA问题:

例如线程1在内存中取出A, 这时线程2在内存中取出A,并且线程2进行了一系列的操作将值变为B,然后线程2又经过一系列的操作将数据变为A,这个时候线程1进行CAS操作发现内存中仍然是A,然后线程1操作成功;
尽管线程1CAS操作成功,但是不代表这个过程没有问题;

ABA问题的解决:
新增一种机制,那就是版本号(类似于时间戳);
AtomicStampedReference类;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值