Welcome to Yumao′s Blog.
Java中在使用Runtime.getRuntime().exec(command)调用系统命令后
一般会调用Process.waitFor()来等待命令执行结束 获取执行结果
今天一个悲剧的事实证明了
即使只是调用了很简单的脚本命令
在调用Process.waitFor()后同样可能发生无休止或者接近于无休止的阻塞
处理完故障之后痛定思痛
决定在代码中加入超时控制
但是Process.waitFor()本身并不支持超时时间设置
一个方法是改用非阻塞的Process.exitValue()方法
然后轮询检查进程状态 这种方式比较消耗CPU
以至于轮询间隔也不能设置得太小 总归不是很完美
另外就是多起一个线程
借助于其他的超时机制来控制
最后使用的代码如下
public class ProcessUtils { /** * 运行一个外部命令,返回状态.若超过指定的超时时间,抛出TimeoutException * @param command * @param timeout * @return * @throws IOException * @throws InterruptedException * @throws TimeoutException */ public static int executeCommand(final String command, final long timeout) throws IOException, InterruptedException, TimeoutException { Process process = Runtime.getRuntime().exec(command); Worker worker = new Worker(process); worker.start(); try { worker.join(timeout); if (worker.exit != null){ return worker.exit; } else{ throw new TimeoutException(); } } catch (InterruptedException ex) { worker.interrupt(); Thread.currentThread().interrupt(); throw ex; } finally { process.destroy(); } } private static class Worker extends Thread { private final Process process; private Integer exit; private Worker(Process process) { this.process = process; } public void run() { try { exit = process.waitFor(); } catch (InterruptedException ignore) { return; } } } }