繁体   English   中英

Java 非最终字段强制使用另一个易变字段的可见性

[英]Java non-final fields force visibility with another volatile field

我最近开始了解 Java Memory Model 是如何工作的(我还不完全了解)。

我现在明白,如果我的类中有非最终的、非易失性字段,那么这些字段的值可能不会立即对其他线程在构造后可见,例如

public class Example {
    Object a;
    Object b;

    public Example() {
      this.a = new Object();
      this.b = new Object();
    }
}

Example e = new Example();

// now imagine we are in another thread
e.a // could this in theory be null?
e.b // could this in theory be null?

我不确定的是天气,如果我添加第三个 volatile 变量并将其设置在最后,是否可以保证对ab的写入对其他线程可见?

public class Example2 {
    Object a;
    Object b;
    volatile Object c;

    public Example2() {
      this.a = new Object();
      this.b = new Object();
      this.c = new Object();
    }
}

// some where else
Example2 e2 = new Example2();
// are e2.a and e2.b guaranteed to be visible to all other threads? I know (e2.c will be)

这不是我特别想使用的东西,但我想了解在这种情况下会发生什么。

构造函数在单个线程中运行,并且在构造函数完成之前实例对其他线程不“可见”。

因此,在此示例中, ab随后在构造函数后设置为 null,则它们只会在其他线程中被视为 null。

volatile关键字解决了可能的优化问题,在该优化中,由于值的本地缓存,一个线程在另一个线程上发生更改后可能会继续使用该字段的旧值。 通过向该字段添加volatile ,可以禁用此类优化。

顺便说一句,如果需要跨线程同步,使用 volatile 字段并不理想。 建议使用java.util.concurrent中的原子类或其他构造。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM