我有以下运行进程的代码,我想知道在运行它时是否有异常。它无缘无故地挂着
Runtime runtime = Runtime.getRuntime();
proc = runtime.exec(command.toString());
ProcessHandler errorStream = new ProcessHandler(proc.getErrorStream(),"ERROR", rdyFilePath);
ExecutorService pool = Executors.newSingleThreadExecutor();
Future future = pool.submit(errorStream);
pool.shutdown();
try {
if(future.get() == null) {
log.info("Done completing error thread");
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}下面是流程处理程序的类
public class ProcessHandler implements Callable<Integer> {
private static Logger log = Logger.getLogger(ProcessHandler.class.getName());
InputStream inpStr;
String strType;
String rdyFile;
public ProcessHandler(InputStream inpStr, String strType, String rdyFile) {
this.inpStr = inpStr;
this.strType = strType;
this.rdyFile = rdyFile;
}
public Integer call() throws FileMetadataException {
StringBuffer sb = new StringBuffer();
try {
InputStreamReader inpStrd = new InputStreamReader(inpStr);
BufferedReader buffRd = new BufferedReader(inpStrd);
String line = null;
while((line = buffRd.readLine()) != null) {
if("ERROR".equalsIgnoreCase(strType)) {
sb.append(line + "\n");
log.info(strType + "->" + line);
}
}
if(sb != null) {
log.info("Error Stream length : " + sb.length());
throw new RuntimeException();
}
buffRd.close();
} catch(IOException e) {
log.error("IOException in ProcessHandler Thread" + e.fillInStackTrace());
System.err.println(e);
throw new FileMetadataException();
} finally {
if(sb != null) {
if(sb.toString().length() > 0 ) {
log.error("Error string buffer length " + sb.length());
// do not create rdy file
} else {
log.error("Error string buffer length : " + sb.length());
File f = new File(rdyFile);
try {
f.createNewFile();
} catch(IOException e) {
log.error("IOException while creating rdy file");
}
}
// create rdy file.
}
}
return sb.length();
}
}
}发布于 2013-09-17 20:22:40
我有以下运行进程的代码,我想知道在运行它时是否有异常。它无缘无故地挂着
如果有一个异常,您的future.get()应该抛出一个ExecutionException -它不会“挂起”。您确定您的异常不是打印出来的,而是在日志或控制台输出中丢失的吗?
在跟踪您的代码时,我发现您的程序在读取完流后无法完成。也许正在读取错误流的进程仍在运行,而InputStream尚未关闭?可能有太多的输出,以至于您正在用StringBuffer填充核心(应该更改为StringBuilder )。
您是否可以使用j控制台附加到应用程序以查看线程是否仍在运行,如果仍在运行,则它在做什么?
if(future.get() == null) {
log.info("Done completing error thread");
}因此,只有当从null方法返回call()时,这才会记录输出。这将永远不会发生,因为唯一的回报是return sb.length();。因此,要么您将从您的call()中得到一个异常,要么您的结果将是一个非空Integer。
发布于 2013-09-17 22:24:20
来自Process javadoc:
由于一些本机平台只为标准输入和输出流提供有限的缓冲区大小,如果不及时写入输入流或读取子进程的输出流,可能会导致子进程阻塞,甚至导致死锁。
根据此警告,您的future.get()方法是挂起的,因为您只使用来自process对象的错误流。在我使用过Process对象的所有平台上,我注意到您需要同时使用错误流和标准输出流。
这是一个很好的工具,它使用多线程方法来确保流程流被消耗。
在本例中,由于您似乎不关心流程的标准输出,所以可以使用StreamHelper类添加类似的内容:
StreamHelper inStreamHelper = new StreamHelper(proc.getInputStream());
inStreamHelper.start();https://stackoverflow.com/questions/18859040
复制相似问题