【发布时间】:2017-03-01 14:30:14
【问题描述】:
当用户单击按钮时,我有一个 GUI 会启动一个新线程 (getFilesThread)。该线程调用下面我的ClearCaseProcess 类实例的start() 方法(我的组织不允许我使用ClearCase Java API),当进程结束时,它会更新GUI。
private static class ClearCaseProcess {
private ArrayList<String> stdout = new ArrayList<>();
private ArrayList<String> stderr = new ArrayList<>();
private ProcessBuilder pb = null;
public ClearCaseProcess(ArrayList<String> commands, String dir) throws IOException {
pb = new ProcessBuilder(commands);
pb.directory(new File(dir));
}
public void start() throws IOException {
long minStart = System.nanoTime();
Process process = pb.start();
Thread sout = new Thread() {
@Override
public void run() {
BufferedReader out = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String outLine = "";
try {
while ((outLine = out.readLine()) != null) {
stdout.add(outLine);
System.out.println(outLine);
}
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
};
sout.start();
Thread serr = new Thread() {
@Override
public void run() {
BufferedReader err = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
String errLine = "";
try {
while ((errLine = err.readLine()) != null) {
stderr.add(errLine);
System.err.println(errLine);
}
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
};
serr.start();
try {
process.waitFor();
long execTime = System.nanoTime() - minStart;
System.out.println("Process '" + description + "' took " + execTime);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}
}
getFiles() 需要从四个不同的ClearCaseProcesses 收集数据。我计划在四个线程中同时运行这些。这些线程中的每一个都有两个关联的辅助线程来消耗stdout 和stderr,如上所示。我假设这将比连续运行四次 ClearCase 更快。不过,目前我只测试了一个 ClearCase 调用。
我的问题是调用Process.start() 和返回Process.waitFor() 之间经过的时间(大约5 分钟)比我在终端上运行相同的ClearCase 命令所经过的时间(大约1.5 分钟)要长得多。我怀疑我的读取 stdout 和 stderr 的循环是罪魁祸首,因为即使是我的打印语句在 NetBeans 控制台中产生输出的速度也很慢。如何加快速度?
【问题讨论】:
-
您是否尝试过在 Netbeans 之外运行 Java 应用程序?
-
嗯,奇怪。假设您首先关心的是运行时...您是否尝试过不从这些流中读取任何内容?只需触发流程命令并测量执行时间?为了证明流会产生开销?
-
@GhostCat,如果进程实际上将任何内容发送到其输出和/或错误流中,那么 Java 程序必须必须使用它,否则外部进程可能永远不会终止。
-
如果外部进程正在产生大量输出,那么问题可能与在两个列表中存储所有输出有关。您可以考虑将输出重定向到文件或空设备,或者将您阅读的所有内容都放在地板上。
-
您是否在动态视图中使用它?你在用setview吗?您使用的是哪个版本的 ClearCase?在哪个操作系统上?
标签: java multithreading process clearcase