Java 创建应用单例的简单方法
Java Simple Way to Create Application Singleton
我正在尝试为我的 Java 应用程序创建一个全局连接池。
我的问题是,当我使用以下方法时:
package mypackage;
public class Singleton
{
private static MyPool connPool;
private Singleton() {}
public MyPool getPool() {
if (connPool == null)
connPool = new MyPool();
return connPool;
}
}
现在,如果我有两个 classes A 和 B,它们使用
在上面导入 Singleton class
import mypackage.Singleton;
然后我将最终调用 new MyPool()
两次,这意味着我将打开与我的资源(例如数据库)的双倍连接。如何确保在我的应用程序中只创建一次池?
我在 Internet 上找到了一些使用反射来完成此操作的复杂方法。有没有更简单(and/or更好)的方法?
我认为您正在寻找单例 class 的线程安全实现。当然,实现此目的的方法是使用枚举,但对于您的情况,您可以实施双重检查锁定以确保没有两个线程可以同时调用 new MyPool()。
此外,我认为在您的代码中,您实际上是在实现工厂 class,而不是真正的单例。您的 MyPool 与 Singleton 不同 class,后者可能具有 public 构造函数。
我已经通过评论进行了适当的修改。
双重检查锁基本上只是检查空检查前后的线程安全,因为整个方法没有同步,所以即使在同步块之后两个线程确实可以在条件中获取空值,因此第二次同步。
此外,我认为您的 getPool() 应该是 static。如果没有显式的 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;
}
}
我正在尝试为我的 Java 应用程序创建一个全局连接池。
我的问题是,当我使用以下方法时:
package mypackage;
public class Singleton
{
private static MyPool connPool;
private Singleton() {}
public MyPool getPool() {
if (connPool == null)
connPool = new MyPool();
return connPool;
}
}
现在,如果我有两个 classes A 和 B,它们使用
在上面导入 Singleton classimport mypackage.Singleton;
然后我将最终调用 new MyPool()
两次,这意味着我将打开与我的资源(例如数据库)的双倍连接。如何确保在我的应用程序中只创建一次池?
我在 Internet 上找到了一些使用反射来完成此操作的复杂方法。有没有更简单(and/or更好)的方法?
我认为您正在寻找单例 class 的线程安全实现。当然,实现此目的的方法是使用枚举,但对于您的情况,您可以实施双重检查锁定以确保没有两个线程可以同时调用 new MyPool()。
此外,我认为在您的代码中,您实际上是在实现工厂 class,而不是真正的单例。您的 MyPool 与 Singleton 不同 class,后者可能具有 public 构造函数。
我已经通过评论进行了适当的修改。
双重检查锁基本上只是检查空检查前后的线程安全,因为整个方法没有同步,所以即使在同步块之后两个线程确实可以在条件中获取空值,因此第二次同步。
此外,我认为您的 getPool() 应该是 static。如果没有显式的 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;
}
}