Tom*_*eck 1 java singleton multithreading synchronization design-patterns
我试图实现单例模式的一个例子.我们的一个问题是运行两个线程,每个线程调用getInstance()并验证只创建了一个Singleton对象的实例.
这是我的Singleton代码;
public class OurSingleton {
static OurSingleton ourSingleton;
static int instanceCounter;
private OurSingleton(){
instanceCounter++;
}
public static synchronized OurSingleton GetSingletonInstance(){
if( ourSingleton == null){
ourSingleton = new OurSingleton();
}
return ourSingleton;
}
public static int getCounter() {
return instanceCounter;
}
}
Run Code Online (Sandbox Code Playgroud)
而我的主要;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
OurSingleton mySingleton = null;
Thread one = new Thread(new GetSingletonInstance(mySingleton));
Thread two = new Thread(new GetSingletonInstance(mySingleton));
one.start();
two.start();
System.out.println("Main: " + mySingleton.getCounter());
}
}
class GetSingletonInstance implements Runnable {
int count = 0;
OurSingleton singleton;
public GetSingletonInstance(OurSingleton ourSingleton){
singleton = ourSingleton;
}
@Override
public void run() {
try {
while (count < 5000000) {
singleton.getSingletonInstance();
count++;
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread: " + singleton.getCounter());
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,我得到以下输出;
主要:0线程:1线程:1
有人可以解释这个输出的原因吗?我认为只有单一的Singleton实例存在.这是否意味着在线程中创建了另一个对象?任何建议表示赞赏!
您应该避免同步该getInstance方法(因为只是为了在初始化后获取实例,这只是一个不必要的开销).以下是懒惰初始化单例的推荐方法:
public class OurSingleton {
private OurSingleton() { }
public static OurSingleton getInstance() {
return Holder.instance;
}
private static class Holder {
private static OurSingleton instance = new OurSingleton();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为只有单一的Singleton实例存在.这是否意味着在线程中创建了另一个对象?
JVM中只存在一个单例实例; 每个线程都显示只有一个实例的事实.
在Java中实现Singleton Pattern的最简单,最安全的方法是使用枚举:
public enum MySingleton {
INSTANCE;
public void doStuffHere() {
//...
}
}
public class ClientClass {
public void myMethod() {
MySingleton mySingleton = MySingleton.INSTANCE;
mySingleton.doStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
您只有一个MySingleton实例,它是线程安全的.