有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带有枚举的java单例与带有双重检查锁定的单例

我想知道在多线程环境中,哪一个在实践中更好。我理解Singleton是因为枚举类型在加载类时创建实例。除此之外,我看不到其他有意义的东西。有什么优点和缺点吗

单例作为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) 个答案

  1. # 1 楼答案

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

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

    使用enum的主要优点是它简单得多,而更复杂的示例是不合理的。双锁示例允许您以一种有趣的方式更改单元测试的单例,但我相信这可以通过另一种方式解决

  2. # 2 楼答案

    单例存在的问题不仅仅是正确的实现

    人们经常使用单例,因此他们不必在应该传递对象的地方传递对象,也不必在多个方法之间传递对象

    有相当多的例子可以用单例实例化jdbc连接

    在需要这种连接的方法中,您可以很容易地访问它,因为它是单例的

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

    并通过

    DBConnection.INSTANCE.getConnection();
    

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

    在代码中,您不会调用DBConnection。实例,而不是在getConnection()上,您的类将有一个用@Inject注释的字段DBConnection。你只要用它

    @Inject
    private DBConnection dBConnection;
    

    这个类将被@Singleton注释为Singleton,框架将保证它是Singleton

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

  3. # 3 楼答案

    使用enum创建一个singleton由于其简单快捷的方式而广受欢迎

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

    例如:

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

    但我认为enum是一种非常直接的方法,它为{}提供了一个更清晰的自我解释代码