• AtomicStampedReference AtomicReference解决CAS机制中ABA问题


    AtomicStampedReference AtomicReference解决CAS机制中ABA问题

    AtomicStampedReference

    AtomicStampedReference它内部不仅维护了对象值,还维护了一个版本号(可以是任何一个整数,它使用整数来表示状态值)。当AtomicStampedReference对应的数值被修改时,除了更新数据本身外,还必须要更新版本号。因此只要版本号发生变化,就能防止不恰当的写入。版本号类似于时间戳。

    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.atomic.AtomicStampedReference;
    
    public class Test {
        /** 
        **/
    
        public static void main(String[] args) {
            AtomicInteger integer = new AtomicInteger(0);
            AtomicStampedReference<Integer> reference = new AtomicStampedReference<>(100,1000);
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    integer.compareAndSet(0,1);
                    integer.compareAndSet(1,0);
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    boolean b = integer.compareAndSet(0, 1);
                    System.out.println("AtomicInteger替换");
                    if(b) System.out.println("0已经被替换为1");
                    else System.out.println("替换失败");
                }
            });
            Thread t3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    reference.compareAndSet(100,-100,
                            reference.getStamp(), reference.getStamp()+1);
                    reference.compareAndSet(-100,100,
                            reference.getStamp(), reference.getStamp()+1);
                }
            });
            Thread t4 = new Thread(new Runnable() {
                @Override
                public void run() {
                    int stamp = reference.getStamp();
                    try {
                        Thread.currentThread().sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    boolean b = reference.compareAndSet(100, -100,
                            stamp, reference.getStamp() + 1);
                    System.out.println("AtomicStampedReference替换");
                    if(b) System.out.println("100已经被替换为-100");
                    else System.out.println("替换失败");
                }
            });
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
    }
    输出结果:
    AtomicInteger替换
    0已经被替换为1
    AtomicStampedReference替换
    替换失败
    

    AtomicReference

    AtomicReference类提供了一个可以原子读写的对象引用变量。 原子意味着尝试更改相同AtomicReference的多个线程(例如,使用比较和交换操作)不会使AtomicReference最终达到不一致的状态。

    import java.util.concurrent.atomic.AtomicReference;
    
    public class ABAObjectTest {
        public static void main(String[] args) {
            SubObject subObject = new SubObject(100,"一百");
            AtomicReference<SubObject> reference = new AtomicReference<>(subObject);
            SubObject subObject1 = new SubObject(200,"二百");
            SubObject subObject2 = new SubObject(300,"三百");
    
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    boolean b = reference.compareAndSet(subObject, subObject1);
                    SubObject object = reference.get();
                    System.out.println(b);
                    System.out.println(object);
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.currentThread().sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("=============");
                    System.out.println(reference.get());
                    boolean b = reference.compareAndSet(subObject, subObject2);
                    System.out.println(b);
                    System.out.println(reference.get());
                }
            });
            t1.start();
            t2.start();
        }
    }
            /*输出结果:
            true
            SubObject{intNum=200, string='二百'}
            =============
            SubObject{intNum=200, string='二百'}
            false
            SubObject{intNum=200, string='二百'}*/
    
    class SubObject {
        public int intNum;
        public String string;
    
        public int getIntNum() {
            return intNum;
        }
    
        public void setIntNum(int intNum) {
            this.intNum = intNum;
        }
    
        public String getString() {
            return string;
        }
    
        public void setString(String string) {
            this.string = string;
        }
    
        public SubObject(int intNum, String string) {
            this.intNum = intNum;
            this.string = string;
        }
    
        public SubObject() {
        }
    
        @Override
        public String toString() {
            return "SubObject{" +
                    "intNum=" + intNum +
                    ", string='" + string + '\'' +
                    '}';
        }
    }
    
  • 相关阅读:
    react 【ref转发forwardRef】【useImperativeHandle】
    node 【redis 使用】
    vue vuerouter 实现原理
    webpack基础 【loader使用】
    【编程范式】范式新感悟
    【领域驱动设计】最佳实践之:单据集合根、命令、状态机
    【读书笔记】架构整洁之道
    Java中的Unsafe在安全领域的一些应用总结和复现
    CVE202222947 Spring Cloud Gateway SPEL RCE复现
    java高版本下各种JNDI Bypass方法复现
  • 原文地址:https://www.cnblogs.com/aslanvon/p/15126713.html
Copyright © 2020-2023  润新知