【问题标题】:Singleton methods thread safe单例方法线程安全
【发布时间】:2012-09-08 14:44:21
【问题描述】:
我有一个问题单例模式和线程。实现是这样的。
public class Singleton {
private static final Singleton instance = new Singleton();
private SomeClass someField;
// and another private fields
private Singleton() {
someField = new SomeClass(some args);
// init another private fields
}
public Singleton getInstance() {
return instance;
}
public void operation() {
//some operations
someField.method();
}
}
(对不起,我不能提供真实的例子。)
接下来的问题是:方法 operation() 线程安全吗?
【问题讨论】:
标签:
java
multithreading
design-patterns
singleton
【解决方案1】:
我们不知道它是否安全 - 我们不知道 someField.method() 做了什么。
我强烈建议您将someField 设为final 字段,就好像单例需要改变状态,那么如果没有额外的同步,它肯定不是线程安全的。如果SomeClass 本身是不可变的并且是线程安全的,那么您应该不需要任何其他同步 - 否则,您将需要。
基本上,单例没有什么“神奇的线程安全”。它只是一个实例,多个线程可以通过静态getInstance() 方法访问它。如果该类是线程安全的,那么无论它是否是单例,它都是线程安全的 - 如果它不是线程安全的,那么将其设为单例将无济于事。
【解决方案2】:
someField.method(); 的线程安全取决于它实际在做什么。如果它正在修改在多个线程之间共享的状态,那么它不是线程安全的。如果不是,它可能是线程安全的。但通常不应假定它是线程安全的。没有代码我不能说更多。
【解决方案3】:
上面回答的答案不是线程安全的。
这可以通过下面的代码进行测试!
public class TestSingleton {
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(10);
for (int j = 0; j < 100000; j++) {
pool.submit(new Thread() {
public void run() {
Singleton.get().add();
}
});
}
pool.shutdownNow();
System.out.println(Singleton.get().getcnt());
}
}
class Singleton {
private static Singleton singleton = new Singleton();
int cnt = 0;
private Singleton() {}
public static Singleton get() {
return singleton;
}
public void add() {
cnt++;
}
public int getcnt() {
return cnt;
}
}