在下面的示例中,假设线程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
!