4

我想知道在多线程环境中哪个在实践中更好。我将 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;
      }

 }
4

3 回答 3

5

通常在多线程应用程序中,更简单、更容易理解的代码更容易工作。

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

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

于 2012-08-12T20:27:53.250 回答
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;

并且该类将仅使用@Singleton 注释为单例,并且框架将确保它是单例。

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

于 2012-08-12T21:33:53.177 回答
1

enum用于创建的方法因其简单快捷的方式而singleton广受欢迎。

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

例如:

public class Test{

      private static Test uniqueInstance = new Test();

      private Test(){}

      public static Test getInstance(){


             return uniqueInstance;     
         }

 }

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

于 2012-08-12T20:51:10.153 回答