将对象声明为volatile

use*_*369 8 java multithreading volatile

如果在Java中将成员变量声明为volatile,这是否意味着所有对象的数据都存储在易失性存储器中,或者对象的引用是否存储在易失性存储器中?

例如,如果我有以下类:

class C{
   int i = 0;
   char c = 'c';
}
Run Code Online (Sandbox Code Playgroud)

如果我声明它的实例如下:

private volatile C obj;
Run Code Online (Sandbox Code Playgroud)

是否将引用存储obj在易失性存储器中,或将obj数据(obj.iobj.c)volatile存储在内存中?

它是否制造obj.cobj.i线程安全?

Bra*_*rad 19

是的,只有对象引用将被JVM认为是易失性的,而不是将驻留在堆上的对象数据本身.如果您要求堆上对象的成员变量是volatile,您当然可以将关键字应用于这些原语

class C {
   volatile int i = 0;
   volatile char c = 'c';
}
Run Code Online (Sandbox Code Playgroud)

Re:你是否使变量线程安全的问题取决于你如何使用变量.正如@gerrytan从Oracle文档中指出的那样,volatile关键字确实有助于读取或写入是原子的,但是请注意,这与它始终是线程安全的不同.考虑以下代码......

if(obj != null) {
    obj.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

执行空检查的线程仍然可能在执行之前被中断obj.doSomething(),而另一个线程设置obj = null.这里需要一些其他机制,例如synchronized块.


Bhe*_*ung 5

private volatile C obj;
Run Code Online (Sandbox Code Playgroud)

那只会使obj不稳定。

它是否使 obj.c 和 obj.i 线程安全?

不。要使它们线程安全,您必须同步对它们的访问。