Singleton with Enum vs Singleton with double-checked locking

时间:2012-08-12 20:12:32

标签: java multithreading singleton

我想知道在多线程环境中哪一个更好。我理解Singleton作为Enum类型在加载类时创建一个实例。除此之外我没有看到任何其他重要的东西。有利有弊吗?

单身作为Enum类型:

 public enum Singleton {
      INSTANCE;
      public void doSomething(){ ... }
 }

单身double-checked locking

 public class Singleton{
      private volatile static Singleton instance;

      private Singleton(){}
      public static Singleton getInstance(){
           if(instance == null){
                 synchronized(Singleton.class){
                       if(instance == null){
                           instance = new Singleton();
                       }
                 }
           }
           return instance;
      }

 }

3 个答案:

答案 0 :(得分:4)

通常在多线程应用程序中,更简单,更易于理解的代码更有可能起作用。

在我看来,第一个例子显着比第二个更简单,这才是最重要的。

使用enum的主要原因是它更简单,更复杂的例子是不合理的。双锁定示例允许您以有趣的方式更改单例以进行单元测试,但我相信这可以通过另一种方式解决这个问题。

答案 1 :(得分:2)

单身人士遇到的问题多于正确的实施问题。

人们经常使用单身人士,所以他们不必传递对象,他们应该在哪里,或者他们必须跨多个方法传递对象。

有很多例子用于实例化与Singleton的jdbc连接。

在需要此连接的方法中,您可以轻松访问它,因为它是一个Singleton。

public enum DBConnection {
  INSTANCE;
  private Connection connection;
  public Connection getConnection(){
    if(connection == null){
      instantiateConnection();
    }
    return connection;
  }
}

并通过

访问它
DBConnection.INSTANCE.getConnection();

但通常最好使用依赖注入和一个非常好的框架。 GUICE例如。

在你的代码中,你不会在DBConnection.INSTANCE上调用,而在getConnection()上,你的Class将有一个用@Inject注释的字段DBConnection。而你只是使用它。

@Inject
private DBConnection dBConnection;

Class将只是注释@Singleton成为Singleton,框架会保证它是一个单身人士。

如果您有不同的环境,例如测试和生产,您可以让框架为每个环境注入不同的对象。

答案 2 :(得分:1)

使用enum创建singleton已经因为简单快捷的方式而受到欢迎。

此外你在这里比较了双重检查锁定,但是还有其他方法,不使用枚举。

<强>例如

public class Test{

      private static Test uniqueInstance = new Test();

      private Test(){}

      public static Test getInstance(){


             return uniqueInstance;     
         }

 }

但我认为enum使用更清晰的自我解释代码 singleton制作了一个非常强大的直接方法。