16深入理解CAS(重点)
Posted zxhbk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了16深入理解CAS(重点)相关的知识,希望对你有一定的参考价值。
什么是CAS?
CAS:Compare and Swap,即比较再交换,直接对内存中的值进行的操作
jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronous同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。
package com.zxh.cas; import java.util.concurrent.atomic.AtomicInteger; public class CASDemo { public static void main(String[] args) { // 创建整型原子类,初始化大小为2020 AtomicInteger atomicInteger = new AtomicInteger(2020); // public final boolean compareAndSet(int expect, int update):expect期望的值,update更新的值 // 如果期望的值是2020,那么就修改为2021,修改成功返回true,否则返回false System.out.println(atomicInteger.compareAndSet(2020, 2021)); System.out.println(atomicInteger.compareAndSet(2020, 2022)); System.out.println(atomicInteger.get()); // 获取内存中存放的值 } }
Unsafe 类
分析源码
1、发现通过unsafe调用的方法
2、这里的Unsafe类,Java可以通过它直接操作内存
3、我们之前使用的方法getAndIncrement
对内存中的值+1操作
-
下面分析这个方法
private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value; =========================== public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } =========================== public final int getAndAddInt(Object var1, long var2, int var4) { // var2这个参数其实就是创建这个对象时,赋值的值。 int var5; do { // getIntVolatile()获取内存中当前对象的值,经过var2偏移后的值 var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); // compareAndSwapInt方法,是再次判断var1当前对象,经过var2偏移后的值,是否等于var5的值,如果等于的话,就对当前内存中的值+var4,也就是+1。(为什么是再次呢?因为do循环中已经获取过一次) return var5; }
CAS : 比较当前工作内存中的值和主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环!
缺点:
1、循环会耗时
2、一次性只能保证一个共享变量的原子性(但是一个变量已经够了)
3、ABA问题
概念图理解
代码模拟
package com.zxh.cas; import java.util.concurrent.atomic.AtomicInteger; public class CASDemo { public static void main(String[] args) { // 创建整型原子类,初始化大小为2020 AtomicInteger atomicInteger = new AtomicInteger(2020); // public final boolean compareAndSet(int expect, int update):expect期望的值,update更新的值 // 如果期望的值是2020,那么就修改为2021,修改成功返回true,否则返回false // ============ 捣乱的线程 ============= System.out.println(atomicInteger.compareAndSet(2020, 2021)); System.out.println(atomicInteger.compareAndSet(2021, 2020)); // ============ 正常执行的线程 ============= System.out.println(atomicInteger.compareAndSet(2020, 2023)); System.out.println(atomicInteger.get()); // 获取内存中存放的值 } }
以上是关于16深入理解CAS(重点)的主要内容,如果未能解决你的问题,请参考以下文章