Java-静态和动态;不实例化对象时是否需要使用volatile?

Java-静态和动态;不实例化对象时是否需要使用volatile?,java,static,thread-safety,volatile,Java,Static,Thread Safety,Volatile,我有一个类ContainerClass,它有一些静态变量。 多个同时运行的线程访问这些静态变量,它们总是需要具有最新的值 线程访问变量时没有容器类的对象,而是像 ContainerClass.variable_A; 我是否仍然需要声明ContainerClass中线程之间共享的变量volatile?线程中是否发生缓存 编辑:为了清晰起见进行了编辑 EDIT2:为了更清晰:多个线程读取这些可变变量的值,但只有一个线程设置它们。由于读取线程中没有对象实例化,读取线程会缓存变量还是始终具有最新版本?

我有一个类ContainerClass,它有一些静态变量。 多个同时运行的线程访问这些静态变量,它们总是需要具有最新的值

线程访问变量时没有容器类的对象,而是像

ContainerClass.variable_A;
我是否仍然需要声明ContainerClass中线程之间共享的变量
volatile
?线程中是否发生缓存

编辑:为了清晰起见进行了编辑


EDIT2:为了更清晰:多个线程读取这些可变变量的值,但只有一个线程设置它们。由于读取线程中没有对象实例化,读取线程会缓存变量还是始终具有最新版本?

快速回答是肯定的。Static是一个实例/类修饰符。它与同步和内存模型无关。而volatile确保1)指令优化不会将对volatile变量的操作交换为之前/之后的任何操作2)在操作volatile变量之前发生的任何事情都写入主存。所以,是的,你确实需要让它变得不稳定


说到这里,我个人认为你的设计不好。公开这种全局静态volatile基本上违反了封装。除非您有这样的性能原因(我想没有),否则静态变量最好是私有成员和方法返回的最新值,以便更好地封装。

您的问题的确切答案是,这取决于。如果这些变量改变了预期的值,并且没有执行额外的同步-那么是的,您需要一些东西来为这些变量的值提供可见性保证,因为
static
修饰符本身与可见性无关<代码>易失性可由您选择


以防变量没有改变,使它们成为最终变量也足以保证可见性。

您确定volatile就足够了吗?如果你曾经做过
ContainerClass.variable\u A++
,volatile就不会让它成为原子的。有很好的例子来回答这个问题<代码>静态不是可见性修改器。它是所谓的
实例/类
修饰符。您关于volatile变量的声明也不正确,它确保了在读取该值之前向volatile变量写入某些内容。当然,您对static的评论是错误的,因为我输入的太快了。虽然我不太同意这个观点。它确保在为同一线程读取volatile值之前向其他变量写入某些内容,而volatile只保证线程之间的最新值,但在读写顺序上不保证任何内容。
volatile
指令不能使用非volatile重新排序,这为我们提供了写入的值的可见性的保证,但是只有在volatile读取之后,这发生在这个volatile变量被写入之后(可能有点不正确,抱歉)。为了实现这一保证,非易失性写入应该发生在易失性写入之前。好的,我们在这里对易失性有相同的观点。您的第一条注释是“在读取该值之前,会向volatile变量写入某些内容”。我想你的意思是“其他变量的某些内容”,而不是“volatile variable”。不,我的意思是在“从”这个变量“读取”这个值之前,总是先将值写入volatile变量。我之前的评论是关于与其他变量的R/W的关系。希望我们现在达到了同样的目的:)