![]() |
1
1
考虑到这一准则。
从你的问题:
易失性读取不会以这种方式与JMM保证冲突。但是,如果多个线程在if之后但在开始实例化volatile变量之前交换,那么最终仍然可以有两个实例。
为了确保不会发生上述情况,必须使用双重检查锁定
注意这里有两个方面需要考虑。
|
![]() |
2
2
如果没有同步,您的代码肯定会被破坏,因为2个线程可能会看到实例的值为空,并且这两个线程都将执行初始化(考虑每行都有一个上下文切换,然后看看会发生什么)。 除此之外,即使是同步的双重检查锁定(DCL)过去也被认为是在Java中被破坏了,因为当运行不同步时,第二个线程可能会以不同的顺序经历初始化操作。 您可以通过添加一个局部变量来修复代码,并在需要读取时将volatile加载到其中:
但是一个更安全的解决方案是使用类加载器作为同步机制,并且还允许您在每次访问单例时停止使用慢速易失性访问:
|
![]() |
3
2
是的,确实如此:易失性读取可能会发生冲突,以至于两个线程将看到引用的空值,并且将执行双实例化。
您还需要双括号初始化和volatile。
那是因为什么时候
没有像处理器缓存分离这样的东西,读和写都是可见的,但是有指令重新排列,所以为了优化,如果处理器不需要它们的结果,可以稍后调用一些指令。同步和易失性的关键是不要重新排列进入它们的线程的指令顺序。这样,如果某个东西是同步的,并且在代码中声明为完成的,那么它确实完成了,其他线程可以安全地访问它。这就是保证之前发生的全部事情。
将其汇总在一起:如果没有适当的同步处理器,则可以初始化对
|
![]() |
4
0
如果你真的需要Java中的一个单元格,可以使用枚举。它为您修复了以下问题:
在第一次访问时,JVM将以线程安全的方式初始化实例。
|
|
user29759326 · 如何返回递归函数中的最后一个值? 7 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 7 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 7 月前 |
![]() |
rudraraj · java中未声明最终变量 8 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 8 月前 |