Java 并发编程之 AtomicStampedReference

Java juc 大约 2163 字

说明

AtomicReference不能保证ABA问题,故引入了版本标记AtomicStampedReference

代码

public class AtomicStampedReferenceDemo {

    public static void main(String[] args) throws InterruptedException {
        AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 1);

        Thread thread1 = new Thread(() -> {
            String reference = ref.getReference();
            int stamp = ref.getStamp();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ref.compareAndSet(reference, "B", stamp, stamp + 1);
        }, "t1");

        Thread thread2 = new Thread(() -> {
            String reference = ref.getReference();
            int stamp = ref.getStamp();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ref.compareAndSet(reference, "A", stamp, stamp + 1);
        }, "t2");

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.println(ref.getReference() + "\t" + ref.getStamp());
    }

}

输出:

B    2

源码解析

AtomicStampedReference底层是使用Pair对象封装了referencestamp字段。

compareAndSet底层源码是判断了Pair对象。

private volatile Pair<V> pair;

private static class Pair<T> {
    final T reference;
    final int stamp;
    private Pair(T reference, int stamp) {
        this.reference = reference;
        this.stamp = stamp;
    }
    static <T> Pair<T> of(T reference, int stamp) {
        return new Pair<T>(reference, stamp);
    }
}

public boolean compareAndSet(V   expectedReference,
                             V   newReference,
                             int expectedStamp,
                             int newStamp) {
    Pair<V> current = pair;
    return
        expectedReference == current.reference &&
        expectedStamp == current.stamp &&
        ((newReference == current.reference &&
          newStamp == current.stamp) ||
         casPair(current, Pair.of(newReference, newStamp)));
}
阅读 80 · 发布于 2021-09-22

————        END        ————

扫描下方二维码关注公众号和小程序↓↓↓

扫描二维码关注我
昵称:
随便看看 换一批