volatile的目的/优势
volatile关键字可以通过让每个线程每次都从内存中获取最新值来使访问变量变慢,这在从不同的线程访问变量时非常有用。但如果在每次更改多线程变量时都使用synchronized(这是我主要做的),那么它们会从volatile中受益吗?或者这是为那些没有显式锁定的变量而设计的?同步是volatile+锁定,使用volatile非常不寻常。如果您正确使用同步,您可能不需要volatile。当您在对象上同步时,对该块内部共享内存的任何更改都将在其他线程在同一对象上同步时立即被看到。volatile是一种在没有同步的情况下保证共享内存可见性的方法。因此,如果您正确使用同步,通常不需要使用volatile关键字。
volatile关键字的目的和优势
在一个多线程程序运行时,如果有一些共享变量没有被声明为volatile,这些线程会创建该变量的本地副本,并在本地副本上进行操作。因此,对该变量的更改不会被反映出来。创建本地副本是因为从缓存内存访问变量比从主存访问变量要快得多。
当我们将变量声明为volatile时,它告诉程序不要创建该变量的任何本地副本,直接从主存中使用该变量。
通过将变量声明为volatile,我们告诉系统它的值可能随时从任何地方改变,因此始终使用主存中保存的值,并始终在主存中对变量的值进行更改,不创建任何变量的本地副本。
请注意,volatile不能替代同步,当一个字段被声明为volatile时,编译器和运行时会注意到该变量是共享的,对其操作不应与其他内存操作重排序。volatile变量不会被缓存在寄存器或缓存中,其中对其他处理器隐藏,因此对volatile变量的读取总是返回任何线程的最近写入。
我从来没有使用过volatile关键字,也从来没有遇到过变量不是最新的问题,所以我不知道你所说的“变量的更改不会被反映出来”的意思。因此,volatile变量实际上更慢,但对于多线程来说仍然更快吗?
volatile变量的访问速度与任何非volatile变量的访问速度相同。但与访问缓存变量的访问相比,它的访问速度较慢,JVM会创建缓存变量以快速执行Java程序。volatile变量仍然保留在主存中,因此对于希望使用它的任何线程来说,它就像是变量的一个位置查找。如果某个变量不是volatile,并且多个线程正在使用它,那么它们可以自由地创建变量的缓存/本地副本,这样该变量就存在于内存中的多个位置,而这可能不是程序员想要的。