【发布时间】:2015-08-10 21:29:27
【问题描述】:
我有一个类似无状态助手的类,我想把它做成一个单例。此类将在不同线程之间共享。
我是否正确,在这种情况下(实例不需要巨大的内存分配大小,因此可以在没有资源和性能影响的情况下多次加载)没有必要使用适当的多线程延迟初始化策略来实现这样的单例( Double Checked Locking & volatile, On Demand Holder idiom, Enum Singleton, Synchronized Accessor)?
使用简单的非多线程惰性初始化版本策略(如下面的代码)来实现这样的单例以减少样板代码的数量是否正确?
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
只有当单例类的状态在不同线程之间共享时,才需要添加适当的多线程版本的单例初始化?
【问题讨论】:
-
至少将构造函数设为私有!就您的问题而言,它实际上取决于“您的物品有多贵?”。在良好的多线程环境中使用上述代码会导致创建许多实例。
-
懒惰的开发者模式(我也是)。有小代码模板; enum 不会开箱即用。您可能还会想到容器管理的持久性,例如 OSGi(=面向服务)或者如果您有多个单例的话。
-
您可以删除整个惰性初始化并将
static final初始化放入类中,该实例将在任何代码能够调用它之前可用 - 它在类加载器运行期间初始化并将除非您使用动态加载并且在超过 1 个地方加载/卸载它,否则永远不会运行两次 -
谢谢,只是忘记添加私有构造函数了。
-
我不明白您为什么不想使用按需持有人。这个来自 wiki 的例子,如果你省略 cmets,比你的方法短 1 行,而且我认为更好。 en.wikipedia.org/wiki/…
标签: java multithreading design-patterns concurrency singleton