在Java中AtomicMarkableReference的"get"方法实现背后的原因是什么?

3
在Java中,可以使用AtomicMarkableReference原子性地更新对象引用和标记位。根据javadoc所述,这个实现会通过创建代表“装箱” [引用,布尔] 对的内部对象来维护可标记的引用。根据该类在Java 8源代码中的实现,这是正确的。请注意,HTML标签已被保留。
package java.util.concurrent.atomic;

public class AtomicMarkableReference<V> {

    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;

    public AtomicMarkableReference(V initialRef, boolean initialMark) {
        pair = Pair.of(initialRef, initialMark);
    }

    // [...] class methods
}

在该类中,get方法的设计有何原因?

(意思是询问AtomicMarkableReference这个类中get()方法的设计背后是否有特殊想法或用意)
public V get(boolean[] markHolder) {
    Pair<V> pair = this.pair;
    markHolder[0] = pair.mark;
    return pair.reference;
}

使用这种布尔数组的意义是什么(而不是返回值对)?这是一个基于并发的选择吗?还是旧代码?

Java 没有也不需要 Pair 类型。 - Louis Wasserman
此外,Java 不想将自己绑定在始终使用基于 Pair 类型的实现上。 - Louis Wasserman
1个回答

3
这是因为Java没有Pair<L, R>类,而且即使标准库中至少有三个类具有private static class Pair,它也不太可能出现。添加Pair类曾多次被OpenJDK开发人员讨论过,但提案总是被拒绝的。这封电子邮件是对为什么不应该将pair作为标准类的很好解释(整个邮件线程也非常有用):

问题在于像Pair这样的类只会更进一步迎合我们从不创建任何自己类型的愿望。当我们被迫创建自己的类型时,我们开始更适当地模拟我们的数据,我相信这也会导致我们在更广泛的粒度级别上创建好的抽象。

只要AtomicMarkableReference不暴露其Pair类,并且在Java中您无法更改传递引用的值(以使调用者能够观察到此类更改),则返回引用和位标志的唯一方法是从方法返回其中一个值,并将第二个值设置为传递的参数数组中。因此,这不涉及并发性,也不涉及遗留问题,而是涉及语言设计决策。

1
非常感谢您的回复!现在我理解了Java背后的设计选择。 - Shadow Template

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接