AtomicStampedReference和AtomicMarkableReference

一、AtomicStampedReference

其实像AtomicBoolean或AtomicLong等这样的变量在多线程修改时,都存在ABA的问题。所谓ABA问题类似于下面伪代码:

第一步 定义一个变量AtomicLong value值为1
第二步 Thread1修改value为2
第三步 Thread2修改value为1
第四步 Thread3通过判断value==1,来检查value是否被修改过

所以Thread3以为value没有被修改过,但实际已经被改过两次了,这就是ABA问题。因此AtomicStampedReference通过引入“版本”的概念,来解决上面的问题。看下面AtomicStampedReference类定义的变量:

    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);
        }
    }

    private volatile Pair<V> pair;

reference即我们实际存储的变量,stamp是版本,每次修改可以通过+1保证版本唯一性。这样就可以保证每次修改后的版本也会往上递增。伪代码如下

第一步 定义一个变量AtomicStampedReference<Long> Pair.reference值为1, Pair.stamp设置为当前时间curTime
第二步 Thread1执行AtomicStampedReference.compareAndSet(1, 2, curTime, curTime+1)
第三步 Thread2执行AtomicStampedReference.compareAndSet(2, 1, curTime+1, curTime+2)
第四步 Thread3通过判断Pair.reference==1&&Pair.stamp==curTime,发现值虽然没有变,但是已经被修改了两次

二、AtomicMarkableReference

AtomicMarkableReference可以理解为上面AtomicStampedReference的简化版,就是不关心修改过几次,仅仅关心是否修改过。因此变量mark是boolean类型,仅记录值是否有过修改。

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

    private volatile Pair<V> pair;
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容