我不确定,如果有人之前曾问过这个问题(如果有这样的道歉)。
从维基百科复制的代码。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
它是如何安全的?是(仅)因为这个班级没有变异状态吗?
如果我像这样修改它会发生什么
public class Singleton {
private static final Singleton instance = new Singleton();
private FancyClass obj1;
private FancyClass obj2;
//feel free to imagine all the getters and setters for obj1 and obj2,
// like getObj1() and so forth
//tricky method
public void doSomething() {
obj1.destroyEnemy();
obj2.destroyFriend();
}
private Singleton() {
obj1 = null;
obj2 = null;
}
public static Singleton getInstance() {
return instance;
}
}
我对设计模式讨论没兴趣,这是我应该维护的那种代码。假设FancyClass是java标准库类。
,上面的'singleton'线程是安全的答案 0 :(得分:3)
你说第一个例子是安全的,这是正确的,因为没有可变状态。
在第二个例子中,单例没有做任何使线程安全的事情,它是否安全取决于FancyClass
是否是线程安全的。将synchronized
放在doSomething
方法上将使其成为线程安全的。
为obj1
和obj2
引入getter和setter也有可能产生问题,那些必须与doSomething
方法在同一个锁上同步,你会即使FancyClass
是线程安全的,也需要锁定,因为如果不同的线程正在改变,那么这些更改需要跨线程可见。
答案 1 :(得分:3)
第一个代码保证调用getInstance()
的所有线程获得对同一Singleton
实例的引用。
对于您的实现(第二个示例),obj1
和obj2
也是如此,因为它们是在创建类本身并且类创建是线程安全的时候创建的(不能是在同一个类加载器中创建两次/“并行”。
doSomething()
方法不是线程安全的。如果您需要原子操作,请将其设为synchronized
。
答案 2 :(得分:1)
Singleton模式根本不是设计为线程安全的,只是为了独特并且禁止创建其他实例。您的代码中唯一的线程安全部分是Singleton实例化private static final Singleton instance = new Singleton();
,因为它在类加载时被调用一次。
但实际上,如果您的类中没有成员通过外部系统调用的方法修改,那么您的Singleton将会/保持ThreadSafe
答案 3 :(得分:0)
关于您的代码 - 由于您将构造函数设为私有,因此永远不会调用它。因此将其声明为null是没有意义的。无论如何,实例变量都会自动分配默认值。
首先是第一个代码
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
被称为早期初始化,与延迟初始化不同,在惰性初始化中,只在需要时才创建实例。要使其线程安全,您需要执行以下操作
public class Singleton {
private static Singleton singleInstance;
private Singleton() {}
public static Singleton getSingleInstance() {
if (singleInstance == null) {
synchronized (Singleton.class) {
if (singleInstance == null) {
singleInstance = new Singleton();
}
}
}
return singleInstance;
}
示例是延迟初始化,但概念保持不变。