我已经实现了Singleton类,如下所示:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
private synchronized static void createInstance() {
instance = new Singletone();
}
public static Singleton getInstance() {
if(instance == null){
createInstance();
}
return instance;
}
}
但我想知道它是否是单例的正确实现。 多线程环境中是否有任何问题。
答案 0 :(得分:7)
public enum Singleton {
INSTANCE;
private int val;
public int getVal() {
return val;
}
}
用法:
Singleton.INSTANCE.getVal();
这是Java版本的完美单例> 5.0你有枚举支持。
Joshua Bloch的Effective Java也提到过。有关它的博客文章:Enum Singleton
<强>更新强>
此外,只有当您100%确定需要单身时,请使用单身人士!它会破坏代码的可测试性!但是你无法避免在工厂里出现这种情况
但请不要滥用它,在实际需要的地方使用它。了解它的用途。
答案 1 :(得分:5)
您的实施几乎是正确的。问题是它不是线程安全的。 2个单独的线程可以同时输入getInstance()
,检查该实例是否为null,然后创建2个类的实例。这是修复:
public static synchronized Singletone getInstance() {
if(instance == null){
createInstance();
}
return instance;
}
请注意synchronized
字。
答案 2 :(得分:2)
除了上面的枚举之外,我遇到的最佳机制称为静态初始化。有了这个,你就依赖于Java内存模型的保证,所以它始终有效。以下是来自an answer to a different question的片段,用于说明这一点:
class Singleton {
static class SingletonHolder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton instance() {
return SingletonHolder.INSTANCE;
}
}
第一次调用SingletonHolder
时,将创建具有Singleton
实例化的SingletonHolder.INSTANCE
类对象。
Java内存模型保证静态代码(new Singleton()
)只能由一个线程执行。因此没有双重检查锁定(这不起作用),也没有不必要的同步。所有后续调用都将获取该实例。
答案 3 :(得分:0)
这是单例模式的正确实现,尽管您实际上并不需要createInstance
方法;你可以在getInstance
中内联这个内容。此外,它拼写为“Singleton”,最后没有“e”。
假设您可以在多线程环境中创建问题。如果两个帧指针同时输入getInstance,则首先输入的那个可以获得Singleton
的实例,而第二个可以获得另一个实例。
这取决于你如何使用它。如果在设置线程之前使用单例,则没有问题。如果这是一个问题,您可以考虑首先初始化单例。您也可以使用方法声明中的synchronized
关键字来解决此问题。
答案 4 :(得分:0)
Singleton不是线程安全的。出于这个原因,引入了Double-checked Locking。
从Java SE 5及更高版本开始,您可以volatile
您的静态实例。当多个线程运行时,Java VM将知道如何正确处理Singleton。
答案 5 :(得分:0)
对于延迟初始化实现,这是你的情况,应该为了线程安全而同步getInstance()方法。
public static synchronized Singleton getInstance()
或者您可以在类加载时初始化它,该加载时已经是线程安全的。
private static Singleton instance = new MySingleton();
答案 6 :(得分:-1)
您的实施似乎没问题。单个JVM中的多线程对于那种单例问题不是问题,但它会在集群(两个或更多JVM)中引起问题。
请参阅http://java.sun.com/developer/technicalArticles/Programming/singletons/了解这些问题。
哦,这是单身人士,不是单身人士。 :)