• CAS ABA问题解决


    CAS(compare and swep)比较然后交换

    通常需要三个参数,一个是预期值,一个是当前值,一个是替换值

    逻辑是 当 预期值 与 当前值 相等时,替换值进行替换,同时返回true。

    ABA问题

    因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么CAS进行检查时会发现它的值没有发生变化,但是实际上已经发生了变化。

    譬如

     对于这个问题Atomic包里面自带的AtomicStampedReference类能够解决这个问题,解决思路就是对于一个值设置一个版本号,更改一次改变一次,进行CAS时不光需要核对Value还要核对版本号。

    代码:

     1 package thread;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 import java.util.concurrent.atomic.AtomicStampedReference;
     5 
     6 /**
     7  * 解决ABA问题,atomic包里面自带的AtomicStampedReference类
     8  */
     9 public class AtomicStampedReferenceDemo {
    10     public static AtomicStampedReference<Integer> atomicStampedReference =
    11             new AtomicStampedReference<Integer>(100,0);
    12 
    13     public static void main(String[] args) {
    14         Thread intT1 = new Thread(new Runnable() {
    15 
    16             @Override
    17             public void run() {
    18                 try {
    19                     TimeUnit.SECONDS.sleep(1);
    20                 } catch (InterruptedException e) {
    21                     e.printStackTrace();
    22                 }
    23                 atomicStampedReference.compareAndSet(100,101,
    24                         atomicStampedReference.getStamp(),
    25                         atomicStampedReference.getStamp() + 1);
    26                 atomicStampedReference.compareAndSet(101,100,
    27                         atomicStampedReference.getStamp(),
    28                         atomicStampedReference.getStamp() + 1);
    29             }
    30         });
    31         Thread intT2 = new Thread(new Runnable() {
    32 
    33             @Override
    34             public void run() {
    35                 int stamp = atomicStampedReference.getStamp();
    36                 System.out.println(stamp);//0
    37                 try {
    38                     //相当于Thread.sleep,能够自定义单位
    39                     TimeUnit.SECONDS.sleep(2);
    40                 } catch (InterruptedException e) {
    41                     e.printStackTrace();
    42                 }
    43                 Boolean b = atomicStampedReference.compareAndSet(100, 101,
    44                        stamp,
    45                         stamp + 1);
    46                 System.out.println(b);//false
    47                 System.out.println(atomicStampedReference.getReference());//100
    48             }
    49         });
    50 
    51 
    52         intT1.start();
    53         intT2.start();
    54     }
    55 
    56 }
     
  • 相关阅读:
    JavaScript高级程序设计之元素大小
    软件测试面试必备的一些基础理论概念
    golang跨平台编译
    gin shoudBind
    requests
    excelize
    gin获取全部参数
    golang随机数及pipe
    不安全代码只会在使用 /unsafe 编译的情况下出现
    MongoDB 比较运算符 $eq$gt
  • 原文地址:https://www.cnblogs.com/frank9571/p/12385347.html
Copyright © 2020-2023  润新知