java多线程(并发)夯实之路-CAS原理与应用深入浅出

 CAS:保护共享资源的无锁实现

 CAS

CompareAndSet,简称CAS(也有Compare And Swap的说法),它是原子的

它会将pre即之前的值和最新值进行比较,如果相同,修改为next,不同则修改失败  

CAS的底层是lock cmpchg指令(X86架构),在单核和多核CPU下都能保证比较-交换是原子的

使用例子如下:

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第1张图片

CAS与volatile

CAS需要volatile支持才能读取到共享变量的最新值实现比较并交换的效果

为什么无锁效率高?

无锁情况下,即使重试失败,线程也在不断运行,而synchronzied会让线程没有锁的时候停止运行,发生上下文切换,进入阻塞(上下文切换成本很高)。

要注意的是,无锁情况下,要保证CPU核心数多于线程数,避免cas线程分不到时间片,发生上下文切换,影响性能

适用场景:CPU核心数多于等于线程数

特点:CAS基于乐观锁的思想,synchronzied基于悲观锁的思想,CAS体现的是无锁并发,无阻塞

并发

CAS应用

原子整数

J.U.C并发包提供了

AtomicBoolean

AtomicInteger

AtomicLong


AtomicInteger方法如下:

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第2张图片

updateAndGet原理:用接口的方法具体实现计算结果和cas操作实现

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第3张图片

原子引用

原子引用可以使引用类型的变量也能进行cas操作,类型有: AtomicReference

AtomicMarkableReference AtomicStampedReference

AtomicReference例子如下

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第4张图片

ABA问题:变量值从A修改为B再修改为A,cas操作仍能够执行成功可以给变量加上一个版本号

AtomicStampedReference(Stamped:时间戳,可以理解为版本号)应用如下

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第5张图片

AtomicMarkableReference可以用来判断变量是否被修改过

应用:

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第6张图片

原子数组

分为:

AtomicIntegerArray AtomicLongArray AtomicReferenceArray

supplier 提供者 ()-> (一个结果)

function 函数 (一个参数)->(一个结果)                                     

consumer 消费者 (一个参数)-> () 

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第7张图片

BiFunction (两个参数)-> (一个结果)                                   

BiConsumer(两个参数)-> ()

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第8张图片

原子更新器

字段更新器:

AtomicReferenceFieldUpdater AtomicIntegerFieldUpdater AtomicLongFieldUpdater

字段更新器可以针对对象的某个域(Field)进行原子操作,只能配合volatile修饰的字段使用,否则会出现异常

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第9张图片

原子累加器

LongAdder,LongAccumulator是专门的累加类

相对于AtomicLong性能更高,因为LongAdder在有竞争时设置多个累加单元(线程1累加Cell[0],线程2累加Cell[1]...最后结果汇总,累加单元不会超过CPU核心数),减少了CAS重试失败的次数。

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第10张图片

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第11张图片

LongAdder原理

cas锁,不要用于实践,while(true)会一直运行,降低性能

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第12张图片

关键的域:

java多线程(并发)夯实之路-CAS原理与应用深入浅出_第13张图片

你可能感兴趣的:(java多线程(并发),java,开发语言)