正确使用Singleton Pattern

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实例存在.这是否意味着在线程中创建了另一个对象?任何建议表示赞赏!

Bhe*_*ung 8

您应该避免同步该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)


m3t*_*man 5

我认为只有单一的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实例,它是线程安全的.