在下面的示例中,假设线程A创建对象X,线程B调用方法getY(),是否需要将变量y声明为volatile才能对线程B可见?

public class X{
   int y;

   public X(){
      y=10;
   }

   public int getY(){
     return y;
   }
}

最佳答案

如果在构造函数中分配一次,原始变量是否需要为volatile


一言以蔽之。 (但是也有其他解决方案。)

在这里可能会影响您的情况是y = 10分配可能不会被刷新,因此第二个线程可能会看到默认的初始值(0)而不是10

可能的解决方案:


y声明为final。假设在构造函数end1之前未“发布” X的实例,JLS保证其他线程将看到y的正确值。
y声明为volatile。缺点是,这会在>> all 之前添加一个内存屏障。即针对每个getY()调用。
确保在线程A中的构造函数完成之后和线程B调用getY之前,在两个线程之间发生一个事件。这可以通过以下方式完成:


通过X变量从A传递volatile实例,
使用同步方法调用传递它,或
让线程A在B线程上调用X之前,将共享的B实例提供给start()





1-...并且您不会使用讨厌的反射,Unsafe或本机代码来破坏final

10-04 19:31