有时候要使用Java调用linux脚本,且需要设置超时时间,以下是我封装的简单的类:
超时使用Thread.join(time)来实现。
public class ProcessUtils {
/**
* @parma taskName 任务名
* @param processName 进程名
* @param cmd
* @param timeout
* 超时时间,如果为0则表示永远不超时
* @return
*/
public static boolean execute(String taskName, String processName, String[] cmd, long timeout) {
BufferedReader infoReader = null;
BufferedReader errorReader = null;
StringBuilder errorMsg = new StringBuilder();
Process process = null;
TimeoutWorker worker = null;
try {
process = Runtime.getRuntime().exec(cmd);
infoReader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
errorReader = new BufferedReader(new InputStreamReader(
process.getErrorStream()));
worker = new TimeoutWorker(process);
worker.start();
worker.join(timeout);//超时时间到或者run方法执行完成(即process.waitFor执行完成)时就会向下执行
if (worker.status != null) {
// info数据
String line = null;
while (infoReader != null
&& (line = infoReader.readLine()) != null) {
System.out.println(line);
}
// error数据
while (errorReader != null
&& (line = errorReader.readLine()) != null) {
errorMsg.append(line).append("\n");
}
if (!errorMsg.toString().isEmpty()) {
System.out.println(errorMsg.toString());
}
}else{//超时
System.out.println(processName + " timeout, timeout is "+ timeout+"...");
}
} catch (InterruptedException e) {
if (worker != null) {
worker.interrupt();
}
Thread.currentThread().interrupt();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
return false;
}
/**
* 用于设置超时的线程
*
*/
private static class TimeoutWorker extends Thread {
private Process process;
private Integer status;
public TimeoutWorker(Process process) {
this.process = process;
}
public void run() {
try {
status = process.waitFor();
} catch (InterruptedException e) {
return;
}
}
}
}
但如ps -ef|grep tomcat的脚本用以上的方法是解决不了的,需要做一些改变,即
cmd = {"ps -ef|grep tomcat"}
改成:
cmd = {"/bin/sh", "-c","ps -ef|grep tomcat"}
就可以了。
网上有说:Runtime.getRuntime().exec()这种调用方式在java虚拟机中是十分消耗资源的,即使命令可以很快的执行完毕,频繁的调用时创建进程消耗十分客观。java虚拟机执行这个命令的过程是,首先克隆一条和当前虚拟机拥有一样环境变量的进程,再用这个新的进程执行外部命令,最后退出这个进程。频繁的创建对CPU和内存的消耗很大。 有空时研究下...