我想知道在多线程环境中哪一个更好。我理解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;
}
}
答案 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
制作了一个非常强大的直接方法。