【发布时间】:2020-07-13 14:00:35
【问题描述】:
我有使用 ProcessBuilder 运行 cmd.exe 进程的代码,当我使用
process.destroy(); CPU 使用率增加(0% > 30%)。每次我启动并销毁 cmd.exe 时,都会出现导致 CPU 使用率高达 100% 的新线程。当 InputStream 结束时,我能以某种方式停止这个循环吗?当服务器以 Ctrl-C 停止并且客户端具有高 CPU 使用率时,在我的另一个应用程序中也是如此。
input.readLine(); 想从不存在的 InputStream 中读取,导致 CPU 使用率过高。卡在这一行了。
我使用 Java 8
代码:
InputStream inputraw = process.getInputStream();
BufferedReader input = new BufferedReader(new InputStreamReader(inputraw));
while(true)
{
String cmd = input.readLine(); //HERE!
//write cmd to console functions.....
}
if (isWindows) {
command = (String.format("cmd.exe"));
} else {
command = (String.format("sh"));
}
ProcessBuilder pb = new ProcessBuilder()
.command(command)
.redirectErrorStream(true);
process = pb.start();
【问题讨论】:
-
(String.format("cmd.exe"))而不仅仅是写"cmd.exe"的目的是什么?除此之外,如果不是您正在积极创建的线程,那么会出现什么样的“新线程”? -
这只是我的代码的一部分。 String.format("cmd.exe") 之前在这里运行 String.format("cmd.exe /c %s",cmd)。
-
String.format("cmd.exe /c %s",cmd)仍然是一种不必要的复杂和低效的表达方式"cmd.exe /c %s" + cmd。但无论如何,关键是你提到但没有提供相关信息的新线程。 -
@Holger 线程不是问题我已经通过在线程中创建 input.readLine 并在我的服务器应用程序超时后将其终止来临时修复它。问题是代码卡在 input.readline() 上。在调试器中代码卡在这里
-
然后,我建议删除“新线程出现”这个误导性短语。我以前见过这种现象,
FileInputStream在尝试从损坏的管道中读取时会使用 100% CPU(在一个核心上)。我会避免使用BufferedReader.readLine()并使用inputStream.read(byteArray, 0, (int)Math.min(inputStream.available(), byteArray.length()))来避免任何阻塞读取并稍后进行处理(转换为字符串,拆分为行)。但是,当您对输出所做的只是将其写入控制台时,请改用ProcessBuilder上的redirectOutput(ProcessBuilder.Redirect.INHERIT)。
标签: java multithreading input process