java - 单例模式的正确使用

标签 java multithreading design-patterns synchronization singleton

我正在尝试实现单例模式的示例。我们的问题之一是运行两个线程,每个线程调用 getInstance() 并验证只创建了一个 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;

    }
}

还有我的主要;

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());

    }       
}

当我运行这段代码时,我得到以下输出;

Main: 0 Thread: 1 Thread: 1

有人可以解释这个输出的原因吗?我原以为只存在单一的单一实例。这是否意味着正在线程中创建另一个对象??任何建议表示赞赏!

最佳答案

您应该避免同步 getInstance 方法(因为它只是在初始化实例后获取实例的不必要开销)。以下是惰性初始化单例的推荐方法:

public class OurSingleton {

    private OurSingleton() { }

    public static OurSingleton getInstance() {
        return Holder.instance;
    }

    private static class Holder {
        private static OurSingleton instance = new OurSingleton();
    }        
}

关于java - 单例模式的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13351590/

相关文章:

c# - 创建大量系统线程并等待 MRE 的影响?

Java多线程向数据库插入百万条记录

java - 在 JTable 中添加 JSpinner 时出现非法参数异常

java - 新手 需要帮助 制作 Java 类和签名

java - 如何创建 Java Web Start 应用程序的线程转储

Javascript 装饰器模式 - 原型(prototype)还是单一函数?

php - 在 JS 处理程序或 PHP ajax 函数中为 ajax 函数生成 html 更好吗?

java - 如何在 Java 中对用户输入进行四舍五入

java - 如何外部化 Tomcat 服务器内多个 Web 应用程序的配置?

C++ 单例类——继承的好习惯