在Java中实现单例模式

RKC*_*KCY 9 java singleton

任何人都可以提供单例模式的例子并解释为什么它们是必要的吗?

Gre*_*osz 32

在走单身路线之前,重新考虑一下.你真的需要一个单身人士吗?如果你在需要实现单例时要求场景,那是因为对它们的需求并没有真正表达出来.你最好不要在你的代码库中引入单例,因为跟随设计模式感觉很酷.

清洁代码会谈 - 全球国家和单身人士

一旦不够

表演者单身人士

然而,真正值得了解的是依赖注入.

现在,如果你真的想用Java实现单例,我会推荐Joshua Bloch的"Effective Java"实现方法:

public class Singleton
{
  public static Singleton getInstance() {
    return SingletonHolder.instance;
  }

  private Singleton() {}

  private static final class SingletonHolder {
    static final Singleton instance = new Singleton();    
  }
}
Run Code Online (Sandbox Code Playgroud)

JLS直到有人呼叫保证JVM不会初始化实例getInstance();

最后需要注意的是,Double Checked Locking Pattern在Java中已经破解,直到Java 5.Java 5内存模型使DCL模式线程安全,但它使得它比SingletonHolder类方法慢,而原始意图是性能优化.

编辑:正如@Luno指出的那样,自本书的第二版以来,首选的方法是:

从版本1.5开始,有第三种方法来实现单例.只需使用一个元素创建一个枚举类型:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() { ... }
}
Run Code Online (Sandbox Code Playgroud)

这种方法在功能上等同于公共字段方法,除了它更简洁,免费提供序列化机制,并提供防止多实例化的铁定保证,即使面对复杂的序列化或反射攻击.虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方法.

  • 实际上,Josh Bloch写道,实现单例的最好方法是使用枚举.枚举MySingletonClass {INSTANCE; 因为它是线程保存,它不会产生序列化问题,也没有安全风险. (7认同)