Java 挥发性+;多线程场景中的同步组合

Java 挥发性+;多线程场景中的同步组合,java,multithreading,synchronized,volatile,Java,Multithreading,Synchronized,Volatile,我对同步内部结构和易失性内部结构有很好的了解 我有一个问题,是以下问题的后续问题: 我对其中一部分感到困惑。如果我严格遵循上面的示例,我必须将volatile添加到许多变量中,但我确信所有多线程应用程序都没有使用volatile+synchronized组合 如果同步不能保证上述示例中的内存一致性,将volatile变量与synchronizationcode组合使用的用例有哪些?该问题/答案中volatile和synchronized的组合仅适用于双重检查锁定 如果您没有执行双重检查锁定,并

我对
同步
内部结构和
易失性
内部结构有很好的了解

我有一个问题,是以下问题的后续问题:

我对其中一部分感到困惑。如果我严格遵循上面的示例,我必须将
volatile
添加到许多变量中,但我确信所有多线程应用程序都没有使用volatile+synchronized组合


如果
同步
不能保证上述示例中的内存一致性,将
volatile
变量与
synchronization
code组合使用的用例有哪些?

该问题/答案中
volatile
synchronized
的组合仅适用于双重检查锁定

如果您没有执行双重检查锁定,并且访问共享变量总是在同一个
synchronized
监视器的保护范围内(如果应用程序没有使用
java.util.concurrent
类,则应用程序最常访问共享变量),那么您就不需要
volatile


无论如何,这并不意味着双重检查锁定是一个好主意。虽然
volatile
+
synchronized
构造将使双重检查锁定工作,但它没有提供任何显著的性能优势,您也可以在@alf对您所指问题的回答中阅读。

该问题/答案中的
volatile
synchronized
组合仅适用于双重检查锁定

如果您没有执行双重检查锁定,并且访问共享变量总是在同一个
synchronized
监视器的保护范围内(如果应用程序没有使用
java.util.concurrent
类,则应用程序最常访问共享变量),那么您就不需要
volatile


无论如何,这并不意味着双重检查锁定是一个好主意。尽管
volatile
+
synchronized
构造将使双重检查锁定工作,但它不会提供任何显著的性能优势,因为您也可以在@alf对所指问题的回答中阅读。

当定义变量
volatile
时,它是从主存而不是注册表读取的

因此,每个处理器将看到相同的值

在双重检查中,变量被定义为
volatile
,以确保在
synchronized
块之外进行检查将拦截大多数情况

如果变量不是
volatile
,代码将正常工作,但如果处理器较多,则可以超出需要进入
synchronized
块内部(变量不为null时也是如此)


如果在
synchronized
块中完成了对变量的所有访问,则根本不需要
volatile

定义变量
volatile
时,从主存而不是注册表读取变量

因此,每个处理器将看到相同的值

在双重检查中,变量被定义为
volatile
,以确保在
synchronized
块之外进行检查将拦截大多数情况

如果变量不是
volatile
,代码将正常工作,但如果处理器较多,则可以超出需要进入
synchronized
块内部(变量不为null时也是如此)


如果在
synchronized
块中完成对变量的所有访问a
volatile
完全没有必要。

注意:实际上对单例使用双重检查锁定是个坏主意,因为a)单例,b)您可以使用
枚举
肯定我使用了一些其他选项,如枚举、惰性加载程序。只是添加了这个问题,通过一些工作代码来提供上下文。我的困惑只是关于组合。双重检查锁定用于单例对象的延迟初始化。此外,volatile可防止可能发生的优化:“此关键字可防止出现编译器试图优化代码的微妙情况,从而在构建完成之前访问对象”(OCP Oracle®Certified Professional Java®SE 8 Programmer II)如果不在单例上使用其他静态方法或变量,则单例的最简单解决方案是使用渴望的解决方案。另一种方法是使用enum,或者使用holder类。注意:实际上对单例使用双重检查锁定是个坏主意,因为a)单例,b)您可以使用
enum
肯定我使用了一些其他选项,如enum、惰性加载程序。只是添加了这个问题,通过一些工作代码来提供上下文。我的困惑只是关于组合。双重检查锁定用于单例对象的延迟初始化。此外,volatile可防止可能发生的优化:“此关键字可防止出现编译器试图优化代码的微妙情况,从而在构建完成之前访问对象”(OCP Oracle®Certified Professional Java®SE 8 Programmer II)如果不在单例上使用其他静态方法或变量,则单例的最简单解决方案是使用渴望的解决方案。另一种方法是使用枚举,或者使用holder类,但是在上面的场景中,作者为了内存一致性的目的使用了这种组合。在单锁条件下,上述代码不起作用。@AdityaW上述代码是双重检查锁定,而对于双重检查锁定(在双重检查锁定中,您在
synchronized
块之外访问共享变量),您需要
volatile
。大多数多线程代码(幸运的是!)没有双重检查锁定,因为它没有什么好处。@AdityaW很好。双重检查代码中的问题源于不同步