实现Singleton设计模式的方法

时间:2011-06-22 19:21:06

标签: java design-patterns

  

可能重复:
  Efficient way to implement singleton pattern in Java

有人可以帮我理解实现设计模式的两种方法吗?我知道一种方法,即将构造函数设为私有。感谢您的任何指示。

5 个答案:

答案 0 :(得分:4)

最简单的实现包括直接在Singleton类的私有字段中实现Singleton:

public class Singleton {
    private static final instance = new Singleton();
    private Singleton() {}
    public Singleton getInstance() { return instance; }
}

其他实现包含单例的“延迟加载”:只有在第一次调用“getInstance”方法时才会创建实例。

为了保护多线程上下文中的代码,有各种方法(double-null-check,inner class等)。

通过Google快速搜索,您会找到更多精确度。

答案 1 :(得分:0)

Singleton设计模式的一个简单例子如下:

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());
  }
}

修改

创建Singleton Pattern的另一种方法如下:

public enum SingletonPattern
{
       INSTANCE;
       // other methods
}

枚举有唯一的构造函数,程序员不能调用它,所以你不能再做任何实例,你不必担心序列化问题,因为默认情况下枚举是可序列化的

答案 2 :(得分:0)

您也可以使用枚举

    public enum Foo {        
    INSTANCE;    
    } 

答案 3 :(得分:0)

一种简单的方法是创建一个只包含静态成员的类。这有效地实现了单例模式,从不允许该类的多个实例。

public class Singleton {
    private static String m_string;
    private static int m_int;
    static {
        // initialization code...
    }

    public static void foo() {
    }
}

当然,这个类作为其他方法的对象是不可通过的,但这对单例来说没有任何意义,因为它们可以直接从代码中的任何地方引用(当然,这是它们最大的缺点,因为它会创建非常不稳定的代码。)

答案 4 :(得分:0)

另一个使用 volatile 关键字的版本。我讨厌 volatile 关键字。没有理智的人会把这个版本带给教授,因为可能的问题是:“ volatile 究竟做了什么以及它是如何工作的?”

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;
    }
}
  • 是的,它是线程安全的。
  • 是的,我检查单身是否为空两次。
  • 是的,它与Benoit的不同,因为这个版本懒惰地实例化单身人士。仅当实际需要实例而不是在加载类时才创建单例(并且块同步)。
  • 是的,它与查理的不同,因为我只有一次同步。创建单例后,我将永远不会再次同步。此外,同步块而不是方法可以减少开销。

注:

  1. 它可能不适用于旧版本的Java。如果你的java版本是旧的,请升级它。如果你不能,那么也可以使用线程安全的Benoit。
  2. 如果您没有使用线程,请不要同步,因为它可能会使性能降低100倍,并在删除synchronized关键字后与Charlie一起使用。
  3. 请不要戏剧。