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 + '\'' +
                '}';
    }
}
posted @ 2021-08-11 08:51  aixueforever  阅读(489)  评论(0编辑  收藏  举报