ways to implement the Singleton design pattern
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
Efficient way to implement singleton pattern in Java
号
有人能帮助我理解两种实现设计模式的方法吗?我知道一种方法,那就是让构造函数私有化。谢谢你的指点。
最简单的实现是直接在singleton类的私有字段中声明singleton:
1 2 3 4 5 | public class Singleton { private static final instance = new Singleton(); private Singleton() {} public Singleton getInstance() { return instance; } } |
其他实现包含在单例的"延迟加载"中:仅当您第一次调用"getInstance"方法时才创建实例。
为了在多线程上下文中保护代码,有各种方法(双重空检查、内部类等)。
通过快速的谷歌搜索,你会发现更多的精确性。
另一个使用volatile关键字的版本。我讨厌易变的关键词。没有理智的人会把这个版本带到教授面前,因为可能的问题是:"volatile到底是做什么的,它是如何工作的?"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Singleton { private volatile static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if(singleton == null) { synchronized (Singleton.class) { if(singleton == null) { singleton = new Singleton(); } } } return singleton; } } |
- 是的,它是线程安全的。
- 是的,我检查了两次singleton是否为空。
- 是的,它不同于Benoit,因为这个版本延迟地实例化了单例。只有在实际需要实例时(而不是在加载类时),才会创建单例(并同步块)。
- 是的,它不同于查理的,因为我只同步过一次。创建单例之后,我将不再同步。此外,同步块而不是方法可以减少开销。
注:
一种简单的方法是创建一个只包含静态成员的类。这有效地实现了单例模式,不允许类的多个实例。
1 2 3 4 5 6 7 8 9 10 | public class Singleton { private static String m_string; private static int m_int; static { // initialization code... } public static void foo() { } } |
当然,类不能作为对象传递给其他方法,但是这对于单例没有意义,因为它们可以直接从代码中的任何地方引用(当然,这是它们最大的缺点,因为它会创建非常不稳定的代码)。
也可以使用枚举
1 2 3 | public enum Foo { INSTANCE; } |
单例设计模式的一个简单示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class SingletonPattern { private static SingletonPattern instance; private SingletonPattern() { } public static synchronized SingletonPattern getInstance(){ if (instance == null) { instance = new SingletonPattern(); } return instance; } public static void main(String arg[]) { System.out.println("The output of two instance:"); SingletonPattern sp=new SingletonPattern(); System.out.println("First Instance:"+sp.getInstance()); sp=new SingletonPattern(); System.out.println("Second Instance:"+sp.getInstance()); } } |
编辑
创建单例模式的另一种方法如下:
1 2 3 4 5 | public enum SingletonPattern { INSTANCE; // other methods } |
枚举只有一个构造函数,程序员不能调用它,因此您不能再创建任何实例,您不必担心序列化问题,因为默认情况下枚举是可序列化的。