java创建应用程序单例的简单方法

kxxlusnw  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(403)

我正在尝试为我的java应用程序创建一个全局连接池。
我的问题是,当我使用以下方法时:

package mypackage;

public class Singleton
{
    private static MyPool connPool;

    private Singleton() {}

    public MyPool getPool() {
        if (connPool == null)
           connPool = new MyPool();
        return connPool;
    }
}

现在如果我有两个类a和b,它们使用

import mypackage.Singleton;

然后我会调用 new MyPool() 两次,这意味着我将打开到我的资源(如数据库)的两次连接。如何确保在应用程序中只创建一次池?
我在网上发现了一些复杂的方法,可以通过反射来实现这一点。有更简单(和/或更好)的方法吗?

siotufzp

siotufzp1#

我认为您正在寻找单例类的线程安全实现。当然,实现这一点的方法是使用枚举,但是对于您的情况,可以实现双重检查锁定,以确保没有两个线程可以同时调用new mypool()。
另外,我认为在您的代码中,您实际上是在实现工厂类,而不是真正的单例。mypool与singleton是不同的类,后者可能有一个公共构造函数。
我已经做了适当的修改和评论。
双重检查锁定基本上只是检查空检查前后的线程安全性,因为整个方法是不同步的,所以两个线程在同步块之后也确实可以得到空值,从而进行第二次同步。
另外,我认为getpool()应该是静态的。如果没有singleton的显式对象,您将无法调用getpool(),我认为您不需要。
修正版本:

package mypackage;

public class Singleton{
    // Instance should be of type Singleton, not MyPool
    private static Singleton connPool;

    private Singleton() {}

    // *static* factory method
    public static Singleton getPool() {

        // Double-check-locking start
        synchronized(Singleton.class){
            if (connPool == null){

                // Double-check-locking end
                synchronized(Singleton.class){

                    //create Singleton instance, not MyPool
                    connPool = new Singleton();
                }
            }
        }
        return connPool;
    }
}

相关问题