当前位置: 首页 > 面试题库 >

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

祁嘉瑞
2023-03-14
问题内容

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

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


问题答案:

这是因为Java没有Pair<L, R>类,并且即使标准库至少具有三个具有的类的事实,Java也可能没有private static class PairPairOpenJDK开发人员多次讨论了添加类的问题,并且提案始终被拒绝。这封邮件很好地解释了为什么不应该将对显示为标准类(另外,整个邮件线程也非常有用):

问题在于,像Pair这样的类只是走得更远,从而沉迷于永远不必创建我们自己的任何实际类型的欲望。当我们被迫创建自己的类型时,我们开始对数据进行更适当的建模,我相信这会导致我们在更广泛的粒度级别上创建良好的抽象。

只要AtomicMarkableReference不公开其Pair类,并且在Java中,您就无法更改传递的引用的值(以这种更改可以被调用者观察到的方式),返回引用和位标志的唯一方法是返回他们从方法,并设置第二个传入作为参数数组。因此,这与并发无关,与遗产无关,也与语言设计决策有关。



 类似资料:
  • 问题内容: C#和Java都定义 易失性读取具有获取语义 易失性写入具有释放语义 我的问题是: 这是定义volatile的唯一正确方法。 如果没有,如果语义相反,情况会完全不同,即 易失性读取具有释放语义 易失性写入具有语义 问题答案: 获取/释放语义的作用并不在于其他线程多久才能看到volatile字段本身的新写入的值,而在于易失性操作在不同线程之间建立事前联系的方式。如果线程A读取了一个vol

  • 我对编程很陌生,我已经自学了将近一个月了,有谁能给我解释一下我代码中错误的原因吗?在“Total(moneyConv(moneySum*moneyRate))”中出错。行,表示实际和形式的论点在长度上是不同的。我检查了我所有的参数,我觉得很好。多谢!

  • 问题内容: 接口隔离原理(ISP)说,许多客户端特定的接口比一个通用接口好。为什么这很重要? 问题答案: ISP指出: 不应强迫客户依赖他们不使用的方法。 ISP与重要特性- 内聚和耦合有关。 理想情况下,您的组件必须高度定制。它提高了代码的健壮性和可维护性。 实施ISP可为您带来以下好处: 高内聚性 -更好的易懂性,鲁棒性 低耦合 -更好的可维护性,高抗变化性 如果您想了解有关软件设计原理的更多

  • 问题内容: 我看过一些D3代码,它们带有类似这样的模式,用于附加元素: 我真的不明白这个片段。为什么选择null?我对D3的理解方式是,如果要添加圆,则应为: 同样,如果要追加HTML段落,则应该为: 类也是如此:如果将元素添加到类中foo,则应该为。 但是, 确实有效!元素被追加。那么,这是什么意思null呢?我在这里想念什么? 注意:这是一个自我回答的问题,试图提供一个针对该主题的“规范”问答

  • 这里已经阐明了和之间的区别。 但我的问题是,为什么我们要使用关键字?从生成的Java代码角度来看没有区别。 静态编程语言代码: 生成:

  • 问题内容: 最近,我通过Crockford的JSLint运行了一些JavaScript代码,它给出了以下错误: 第1行第1个字符处的问题:缺少“使用严格”语句。 通过搜索,我意识到有些人将其代码添加到了JavaScript中。添加语句后,错误停止出现。不幸的是,谷歌没有透露此字符串语句背后的许多历史。当然,它一定与浏览器如何解释JavaScript有关,但是我不知道会有什么影响。 那么到底是什么,