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
代码 。