2

在 java 中,AtomicMarkableReference可用于以原子方式更新对象引用以及标记位。

javadoc指出:

实现说明:此实现通过创建表示“盒装”[reference, boolean] 对的内部对象来维护可标记引用。

根据该类的 java 8 源代码中可以看到的内容,这是正确的:

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方法的设计背后有原因吗?

public V get(boolean[] markHolder) {
    Pair<V> pair = this.pair;
    markHolder[0] = pair.mark;
    return pair.reference;
}

使用这种布尔数组有什么意义(而不是返回一对值)?是并发驱动的选择吗?或者可能是遗留代码?

4

1 回答 1

3

这是因为 Java 没有Pair<L, R>类并且可能不会,即使标准库至少有三个类具有private static class Pair. PairOpenJDK 开发人员不止一次讨论了添加类,并且提案总是被拒绝。这封邮件很好地解释了为什么不应该将 pair 呈现为标准类(另外,整个邮件线程非常有用):

问题在于,像 Pair 这样的类只是更进一步地满足了永远不必创建我们自己的任何实际类型的愿望。当我们被迫创建自己的类型时,我们开始更恰当地对数据进行建模,我相信这也会引导我们在更广泛的粒度级别上创建良好的抽象。

只要AtomicMarkableReference不公开其Pair类并且在 Java 中您不能更改传递的引用的值(以这种更改将被调用者观察到的方式),返回引用和位标志的唯一方法是返回一个它们来自方法并将第二个设置为作为参数数组传递。所以这不是关于并发性,也不是关于遗留问题,而是关于语言设计决策。

于 2016-05-10T18:19:01.753 回答