加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 参考类型的易失性 – 它是否始终避免因JMM而发布引用问

发布时间:2020-12-14 05:54:27 所属栏目:Java 来源:网络整理
导读:假设这堂课: public class AmIThreadSafe { private int a; private int b; AmIThreadSafe(int a,int b) { this.a = a; this.b = b; }} 假设实例对此类的引用(声明为volatile)可以被一些线程访问(导致竞争条件),只要这个(引用)转义: volatile AmIThreadSaf
假设这堂课:
public class AmIThreadSafe {

    private int a;
    private int b;

    AmIThreadSafe(int a,int b) {
        this.a = a;
        this.b = b;
    }
}

假设实例对此类的引用(声明为volatile)可以被一些线程访问(导致竞争条件),只要这个(引用)转义:

volatile AmIThreadSafe instance = new AmIThreadSafe(1,2);

在这里,我确信分配实例引用的事实发生在线程读取之前.

但是AmIThreadSafe的领域呢?

外部volatile关键字是否也意味着关于a和b字段的事先关系?
或者由于在构造函数中重新排序的潜在语句,是否有可能最终得到任何线程看到陈旧值(在本例中为int以来的默认值为0)?

换句话说,我应该声明a和b final或volatile来防止JMM的任何意外,或者只是在实例的引用上指示volatile吗?

—————-更新的帖子 – 一个好的答案:————————— –

以下文章通过其样本证实,在我的情况下,a和b受到保护,不受JMM优化的影响,这些优化可以防止永久发生在之前的关系.

http://jeremymanson.blogspot.fr/2008/11/what-volatile-means-in-java.html

解决方法

将实例声明为volatile不会使其字段变得不稳定,但如果我正确地理解了您的问题,那么 – 是的,在您的情况下就足够了.

每§17.4.5 of the spec:

>一个线程中的易失性写入发生在另一个线程中的任何后续易失性读取之前.
>同一个线程中的语句具有您期望的之前发生的关系.
>在关系传递之前发生.

因此,如果一个线程将实例视为已初始化,则实例的初始化发生在它之前,并且实例的字段的初始化发生在此之前,因此线程将感知实例的字段已经初始化.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读