用Java打开新流程并保持当前流程的打开状态



有一项任务要将我们的软件的新版本制作到新客户端,我需要让应用程序正常运行,这样,最初启动的应用程序就会启动另一个,并在后面保持打开状态。当新的开始时,原来的一个是关闭的。原始应用程序是一种加载器,它的全部目的是从服务器下载其他应用程序并运行其中一个。这就是为什么使用FileLock的原因,这可能也是为什么我不知道如何保持原始文件在后面打开并成功打开新文件的原因。我设法在Linux中实现了这一点,但不幸的是,我们的客户端使用Windows 10…

一些变量:

private final List<FileLock> locks = new ArrayList<FileLock>();
private final File applicationPath;
private final String application;

装载机构造函数

public Loader(String[] args) throws IOException {
this.args = args;
applicationPath = new File(THIS_DIRECTORY, application + ".jar");
tryLock("loader");
tryLock(application);
}

load()是在构造函数生成后在main中调用的,没有什么特别的。

private void load() throws Exception 
checkAndDownloadUpdate(application, applicationPath);
String javaBin = getJavaBinary();
List<String> command = new ArrayList<String>();
command.addAll(Arrays.asList(javaBin, THIS_FILE.getAbsolutePath(), "-jar", applicationPath.getAbsolutePath()));
command.addAll(Arrays.asList(args));
new ProcessBuilder(command).start();
}

TryLock:

private void tryLock(String name) {
File path = new File(THIS_DIRECTORY, name + "_lock");
long waitUntil = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10);
while (System.currentTimeMillis() < waitUntil) {
try {
FileLock fileLock = tryLock(path);
if (fileLock != null) {
locks.add(fileLock);
return;
}
}
}

在Linux中,我可以将tryLock()的内容替换为return,并将waitFor()添加到Processbuilder的命令中,从而使应用程序按我想要的方式工作。在windows中,新的应用程序直到第一个被杀死才启动。

当新进程启动时,问题似乎会出现,在Windows10中,Java调用Unsafe.park()方法,它会停止,直到原始进程关闭。

我认为这是因为Windows中的文件句柄会阻止第二个进程锁定文件。只有当第一个进程释放锁时,第二个进程才能获得它。

我会尽量避免文件锁定,只监控子进程

ProcessBuilder builder = new ProcessBuilder("comman.exe");
Process process = builder.start();
if (process.isAlive()) {
//wait
}

所以我必须使用ProcessBuilder的inheritIO方法才能打开新流程。现在它按预期工作。还为进程添加了waitFor:

ProcessBuilder builder = new ProcessBuilder(command);
builder.directory(new File(workingDir.toString()));
builder.inheritIO();
Process p = builder.start();
p.waitFor();

相关内容

  • 没有找到相关文章

最新更新