我在这里到那里读到它是固定的,然后我发现了这一点……有人可以最后说它是否损坏了?
这取决于您所说的“它”。
如果您问是否可以使用volatile进行DCL,那么答案是是的,发布Java5。(Java的原始语义
volatile没有很好定义,这意味着在
volatileJava
5之前使用a 不是解决方案。)
如果您询问是否可以在不使用volatile的情况下进行DCL,那么答案是“否”。Java 5内存模型的更改不会使用非易失性
instance变量“修复”
DCL的原始Java实现。
如果您要问是否将DCL用于延迟初始化的单例仍然是一个好主意,那么答案是否定的(我认为):
有更好的方法来实现延迟初始化的单例。使用
enum
是其中之一。由于DCL习惯用法仍然容易出错并且不被很好地理解1,因此最好避免这种情况。
同步性能的提高很大程度上消除了对DCL的需求。
枚举和静态init将在类加载时初始化单调(如果我输入错误,请纠正我)。
我想,那你就错了。类初始化也很懒。除非您强制执行,否则它不会在上课时发生。例如,通过使用3
-精氨酸过载的
Class.forName。 JLS
12.4.1列出了确定何时发生的规则。
这样做的结果是,您可以确保基于枚举的单例的初始化延迟进行,并且绝对可以安全地完成。
顺便说一句,对延迟初始化的严格要求使我想到您的应用程序设计中存在问题。至少,它引入了脆弱性……无论如何实现延迟初始化。
1-如果“普通的Joe程序员”不理解DCL的复杂性,那么在他可能需要维护的代码中使用DCL是一个坏主意。你比普通的Joe程序员更聪明。



