我正在使用下面的代码从输入数据生成报告。当只有少量数据时,以下代码可以正常工作。但是,当数据量变大时,我的程序挂起,必须使用任务管理器关闭该应用程序才能终止该进程。
public void launchReport() {
if( selectionRulesRespected ) {
final Process p;
final String userNameParLine = getUserNameParLine();
final String injParLine = getFilterByFieldParLine();
writeTmpParFile(tmpParFilePath, new String[]{userNameParLine, injParLine});
try {
final ProcessBuilder builder;
if( exporting != null && "TRUE".equals(exporting.toUpperCase()) ) {
builder = new ProcessBuilder("cmd", "/c", batFilePath, reportName, tmpParFilePath, exportFilePath);
}
else {
builder = new ProcessBuilder("cmd", "/c", batFilePath, reportName, tmpParFilePath);
}
//builder.directory( new File(viewerDirPath));
p = builder.start();
p.waitFor();
} catch (final IOException e) {
PlanonMessageDialog.showErrorDialog(ioError);
} catch (final InterruptedException e) {
e.printStackTrace();
}
} else {
PlanonMessageDialog.showErrorDialog(wrongItem);
}
}
应用程序挂起,因为此方法等待进程完成。我可以使用哪些选项?
答案 0 :(得分:0)
您的 java 代码使用 p.waitFor() 等待进程终止。但是该进程写入 stdout/stderr,缓冲区已满,因此 Windows 阻止它进一步执行 - 相反,它等待缓冲区被清空。两个进程互相等待——这是一个典型的死锁。
为了防止这种情况,将 p.waitFor() 替换为检查进程是否已退出的循环。如果不是,则从 stdout 和 stderr 读取。
另见https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Process.html