Singleton with Enum vs Singleton with double-checked locking

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

Singleton as Enum类型:

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

Singleton 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; } } 

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

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

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

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

人们经常使用Singletons,因此他们不必传递对象,他们应该在哪里或者他们必须跨多个方法传递对象。

有一些例子用于实例化与Singleton的jdbc连接。

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

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

并通过访问它

 DBConnection.INSTANCE.getConnection(); 

但通常最好使用dependency injection和一个很好的框架来实现它。 GUICE例如。

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

 @Inject private DBConnection dBConnection; 

这个类只是用@Singleton作为Singleton注释,框架会保证它是一个单例。

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

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

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

例如:

 public class Test{ private static Test uniqueInstance = new Test(); private Test(){} public static Test getInstance(){ return uniqueInstance; } } 

但我认为enum是一个非常直接的方法,用一个更清晰的自我解释 singleton 代码