我已经阅读了不同的文章,例如Double-checked locking: Clever, but broken并且我理解以下代码在多线程使用中被破坏的原因。
class SomeClass {
private Resource resource = null;
public Resource getResource() {
if (resource == null) {
synchronized {
if (resource == null)
resource = new Resource();
}
}
return resource;
}
}
然而,根据它的解释,当一个线程退出一个同步块时,它会执行一个写屏障——它必须在释放锁之前将该块中修改的所有变量刷新到主内存。因此,当线程 A 运行到同步块时,然后依次执行以下过程:
- 将为新的 Resource 对象分配内存;
- 将调用 Resource 的构造函数,
- 初始化新对象的成员字段;
- SomeClass 的字段资源将被分配对新创建对象的引用
最后,在线程 A 退出同步块之前,它会将其本地资源对象写回主存,然后线程 B 将在运行到同步块时从主内存中读取这个新创建的资源。
为什么线程 B 看到这些内存操作的顺序可能与线程 A 执行的顺序不同?我认为线程 B 不会知道资源对象已创建,直到线程 A 从同步块退出时将其本地内存刷新到主内存,因为线程 B 只能从可共享的主内存中读取资源对象?
请纠正我的理解......谢谢。