如何修复JVM中的单例?

时间:2014-07-10 15:03:06

标签: java jvm singleton

我目前正在开发用于执行微积分的Java应用程序。我的应用程序将作为jar文件分发,对于每个微积分,我必须执行我将使用脚本启动我的jar。我的问题如下:我已经创建了一个用于执行数据库查询的单例类,但我不知道如何在两个jar执行之间修复JVM中的单例。我试图启动一个存储单例然后无限等待的空类,但是当我执行我的jar程序时,没有检索单例但是实例化了......我的代码如下:

将单例保留在JVM中的主程序:

/**
 * Entry point for the singleton generation
 * @author yann.blanc
 *
 */
public class MainSingleton {
    /**
     * Entry point
     * @param args Command line arguments, used to define the request type
     */
    public static void main (String[] args) {
        try {
            /*Here my singleton is instantiated*/
            DatabaseServiceSingleton service = DatabaseServiceSingleton.getInstance();
            while (true)
            {
                Thread.sleep(1000);
            }
        } catch (ServiceException e) {
            e.printStackTrace();
            System.exit(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
}

我的单身人士:

public final class DatabaseServiceSingleton implements IDatabaseService {

    private static DatabaseServiceSingleton instance = null;

    /*PARAM and FUNCTIONS OMIT FOR A BETTER READABILITY*/

    /*Constructor with exception to ensure that clients are stopped if the singleton can't be instantiated*/
    private DatabaseServiceSingleton() throws ServiceException {
        try {
            /*Get the current path*/
            String urlCourante = getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
            String[] tab;
            if(urlCourante.contains("\\")){
                tab = urlCourante.split("\\");  
            } else {
                tab = urlCourante.split("/");   
            }
            for(int i = 0; i < tab.length -1; i++) {
                pathFolder += tab[i];
            }
            /*Get configuration informations*/
            getConfiguration();
            /*Init database connectors*/
            initBaseConnexion();
            System.out.println(this.getClass().getClassLoader().toString());
        } catch (Exception e) {
            throw new ServiceException("Problème d'entrée sortie lors de la lecture du fichier "
                    + "de configuration. Le service n'a pas pu être instancié : "+e.getMessage());
        }
    }

    /*Method for retrieve the singleton instance*/
    public static synchronized DatabaseServiceSingleton getInstance() throws ServiceException {
        if (instance == null) {
            instance = new DatabaseServiceSingleton();
        }
        return instance;
    }
}

我确信它会起作用......你能解释一下为什么它不行吗? 谢谢你的帮助:)

编辑:我已经检查了类加载器,它总是一样的(对于jar应用程序和MainSingleton)

2 个答案:

答案 0 :(得分:1)

单例是一种设计模式,它保证给定类只有一个实例在同一个JVM中*

你要做的是在两个不同的jvms之间共享一个单例实例(每个java.exe进程是一个单独的jvm)。你不能这样做。就像现在一样,每个java进程(== jvm)都会初始化自己的单例实例@startup(因此保持自己的连接)。

如果您对此感到不满意, 可以做的是在第3个后台进程(因此是第3个jvm)维护数据库连接,并让所有其他jvms运行在同一个机器通过这个工作(像代理)。这会使代码变得非常复杂,可能不需要。

*即便如此,也有一些涉及类加载器层次结构的场景。

答案 1 :(得分:0)

每次运行带有java -jar ...的jar时,都会启动新的JVM。您不能使用之前运行的对象。