Java Executor framework future.get()挂起
我有以下运行进程的代码,我想知道在运行进程时是否出现异常。它无缘无故挂着Java Executor framework future.get()挂起,java,multithreading,Java,Multithreading,我有以下运行进程的代码,我想知道在运行进程时是否出现异常。它无缘无故挂着 Runtime runtime = Runtime.getRuntime(); proc = runtime.exec(command.toString()); ProcessHandler errorStream = new ProcessHandler(proc.getErrorStream(),"ERROR", rdyFilePath); ExecutorService pool = Executors.newSin
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();
}
下面是process handler的类
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();
}
}
}
公共类ProcessHandler实现可调用{
私有静态记录器log=Logger.getLogger(ProcessHandler.class.getName());
InputStream-inpStr;
字符串strType;
字符串rdyFile;
公共ProcessHandler(InputStream InputStr、字符串strType、字符串rdyFile){
this.inpStr=inpStr;
this.strType=strType;
this.rdyFile=rdyFile;
}
公共整数调用()引发FileMetadataException{
StringBuffer sb=新的StringBuffer();
试一试{
InputStreamReader InputStrd=新的InputStreamReader(InputStr);
BufferedReader buffRd=新的BufferedReader(inpStrd);
字符串行=null;
而((line=buffRd.readLine())!=null){
if(“ERROR”.equalsIgnoreCase(strType)){
sb.追加(第+行“\n”);
日志信息(strType+“->”+行);
}
}
如果(sb!=null){
log.info(“错误流长度:+sb.length());
抛出新的RuntimeException();
}
buffRd.close();
}捕获(IOE异常){
错误(“ProcessHandler线程中的IOException”+e.fillInStackTrace());
系统错误println(e);
抛出新的FileMetadataException();
}最后{
如果(sb!=null){
如果(sb.toString().length()>0){
log.error(“错误字符串缓冲区长度”+sb.length());
//不要创建rdy文件
}否则{
log.error(“错误字符串缓冲区长度:+sb.length());
文件f=新文件(rdyFile);
试一试{
f、 createNewFile();
}捕获(IOE异常){
log.error(“创建rdy文件时发生IOException”);
}
}
//创建rdy文件。
}
}
返回某人的长度();
}
}
}
我有以下运行进程的代码,我想知道在运行进程时是否出现异常。它无缘无故挂着
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();
}
如果出现异常,您的future.get()
应该与ExecutionException一起抛出,它不会“挂起”。您确定您的异常没有被打印出来,而是以某种方式丢失在日志或控制台输出中吗
在跟踪您的代码时,我认为您的程序在读取完流之后没有办法不完成。您正在读取其错误流的进程可能仍在运行,InputStream
尚未关闭?也许有太多的输出,您正在用StringBuffer
填充内核(应该改为StringBuilder
btw)
您能否使用jconsole连接到应用程序,以查看线程是否仍在运行,如果仍在运行,它在做什么
if(future.get() == null) {
log.info("Done completing error thread");
}
因此,只有从call()
方法返回null
时,才会记录输出。这永远不会发生,因为唯一的返回是return sb.length()代码>。因此,要么您将从调用()中得到一个异常
,要么您的结果将是一个非空的整数
我有以下运行进程的代码,我想知道在运行进程时是否出现异常。它无缘无故挂着
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();
}
如果出现异常,您的future.get()
应该与ExecutionException一起抛出,它不会“挂起”。您确定您的异常没有被打印出来,而是以某种方式丢失在日志或控制台输出中吗
在跟踪您的代码时,我认为您的程序在读取完流之后没有办法不完成。您正在读取其错误流的进程可能仍在运行,InputStream
尚未关闭?也许有太多的输出,您正在用StringBuffer
填充内核(应该改为StringBuilder
btw)
您能否使用jconsole连接到应用程序,以查看线程是否仍在运行,如果仍在运行,它在做什么
if(future.get() == null) {
log.info("Done completing error thread");
}
因此,只有从call()
方法返回null
时,才会记录输出。这永远不会发生,因为唯一的返回是return sb.length()代码>。因此,您将从调用()中得到一个异常,或者您的结果将是过程中的一个非空整数
由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能会导致子流程阻塞,甚至死锁
根据此警告,您的future.get()
方法将挂起,因为您只使用来自process对象的错误流。在我使用过的所有平台上,我发现您需要使用错误和标准输出流
是一个很好的工具,它使用多线程方法来确保使用进程流
在本例中,由于您似乎不关心流程的标准输出,因此可以添加类似的内容,借用StreamHelper
类:
StreamHelper inStreamHelper = new StreamHelper(proc.getInputStream());
inStreamHelper.start();
从过程
javadoc:
由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能会导致子流程阻塞,甚至死锁
根据此警告,您的future.get()
方法将挂起,因为您