EnityManagerFactory Singleton。请看看?

时间:2011-05-17 11:49:17

标签: java jpa singleton

如果这看起来很稳固,那我真是太好了。它没有给出任何错误,但我只想仔细检查,因为我遇到了c3p0的池问题。只是检查一下这里是否有任何原因。提前谢谢!

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


public class EntityManagerFactorySingleton {
    private static EntityManagerFactorySingleton singleton;
    private EntityManagerFactory emf;

public EntityManagerFactorySingleton(){
    emf = Persistence.createEntityManagerFactory(ConfigList.getProperty(Config.PERSISTENCE_UNIT), System.getProperties());
}

public synchronized static EntityManagerFactorySingleton getInstance() {
   if(singleton == null) {
    singleton = new EntityManagerFactorySingleton();
   }
   return singleton;
}

public EntityManagerFactory getEntityManagerFactory(){
    return emf;
}

}

3 个答案:

答案 0 :(得分:2)

您的代码不是“稳固”:

  • 构造函数必须是单例
  • 的私有
  • 您不应该同步getInstance()方法,尽管您需要执行初始化线程安全。那是因为在初始化之后,所有需要该实例的线程都必须等待彼此(这是一个无用的瓶颈)。 仅当您的实例为null时,才调用执行初始化的同步(私有)方法;在该方法内部,如果实例为null,则再次检查 。另一种方法是拥有一个保存实例的私有内部类SingletonHolder,因此您将依赖类加载器来执行线程安全的初始化。

但是,如果你不能(不想)避免使用单例,那么一个非常好的选择就是枚举,只定义了一个常量:INSTANCE;

public enum EntityManagerFactorySingleton {
    INSTANCE;

    // all your code -- fields, constructor, instance / static methods get in here
    // you can still have the `getInstance()` static method returning INSTANCE, if you want.
}

唯一的缺点是您无法对INSTANCE执行延迟初始化,但您现在可以进行线程安全,并且可以毫不费力地进行序列化或克隆问题。

答案 1 :(得分:0)

  1. 代码不是线程安全的。(抱歉,错过了synchronized

  2. You should not use singletons

  3. 相反,使用像Springguice这样的DI框架,或者您的部署环境已经提供了一个。

    这将使您的代码更加健壮,更易于测试。

答案 2 :(得分:0)

回答您的问题 - 我认为您应该将构造函数设为私有,以确保其他类无法实例化另一个EntityManagerFactorySingleton。但是,如果没有发生这种情况,那么我就没有理由认为这个类会导致汇集问题。