我目前正在开发用于执行微积分的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)答案 0 :(得分:1)
单例是一种设计模式,它保证给定类只有一个实例在同一个JVM中*
你要做的是在两个不同的jvms之间共享一个单例实例(每个java.exe进程是一个单独的jvm)。你不能这样做。就像现在一样,每个java进程(== jvm)都会初始化自己的单例实例@startup(因此保持自己的连接)。
如果您对此感到不满意, 可以做的是在第3个后台进程(因此是第3个jvm)维护数据库连接,并让所有其他jvms运行在同一个机器通过这个工作(像代理)。这会使代码变得非常复杂,可能不需要。
*即便如此,也有一些涉及类加载器层次结构的场景。
答案 1 :(得分:0)
每次运行带有java -jar ...
的jar时,都会启动新的JVM。您不能使用之前运行的对象。