cas详解和unsafe魔法类·


CAS全程  Compare And Swap,比较并交换,它低层调用的是基于硬件平台的汇编指令,指令叫cmpxchg,低层会判断当前系统是多处理器,如果是则cmpxchg指令会添加lock前缀,如果不是就不加lock前缀,java提供的Unsafe方法就是调用汇编指令封装的。

cas操作过程:

获取内存中的值,然后拿着旧的预期的值和内存中的值作比较,如果比较相等,再用新的值去替换到内存的值,如果内存的值变化了就替换成功,如果没有成功会做自旋重试进行比较。保证每次只有一个线程能够执行。

cas是一种乐观锁,不需要加锁。

乐观锁:

每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。
如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。
由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作 (乐观锁的一种实现方式CAS实现的)
 

cas缺点:

1、cas操作在并发较高的情况下,会导致多线程同时反复尝试修改变量不成功,做循环重试操作,会导致cpu开销很大。

2、cas操作只能保证一个变量的原子性操作,不能保证整个代码块的原子性。用Synchronize锁活ReentrantLock锁解决。

3、存在ABA问题。线程1准备将变量由A修改成B,但是线程2在之前已经将变量由A修改成C,再由C修改成A,线程1执行cas操作发现变量仍是A,所以线程1也能cas成功。

ABA问题需要用一个版本号解决,每次修改后版本号递增操作,在比较内存中的值和旧的预期的值相等的时候,还需要版本号的比较相等,两个相等才能替换成新的值。

======================================================================

java提供了Unsafe魔法类,封装的cas操作的汇编指令。主要三个方法

unsafe方法还提供能够访问对外内存的方法

Java锁和同步器框架的核心类AbstractQueuedSynchronizer,就是通过调用LockSupport.park()和LockSupport.unpark()实现线程的阻塞和唤醒的,而LockSupport的park、unpark方法实际是调用Unsafe的park、unpark方式来实现。

Atomic类的实现就是用了Unsafe实现的

基本类:AtomicInteger、AtomicLong、AtomicBoolean

引用类型:AtomicReference、AtomicReference的ABA实例

AtomicStampedRerence、AtomicMarkableReference; 数组类型:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray 属性原子修改器(Updater):AtomicIntegerFieldUpdater、 AtomicLongFieldUpdater、AtomicReferenceFieldUpdater

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值