首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Executor框架future.get()挂起

Executor框架future.get()挂起
EN

Stack Overflow用户
提问于 2013-09-17 20:11:24
回答 2查看 2.1K关注 0票数 0

我有以下运行进程的代码,我想知道在运行它时是否有异常。它无缘无故地挂着

代码语言:javascript
运行
复制
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();
}

下面是流程处理程序的类

代码语言:javascript
运行
复制
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();
        }

    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-09-17 20:22:40

我有以下运行进程的代码,我想知道在运行它时是否有异常。它无缘无故地挂着

如果有一个异常,您的future.get()应该抛出一个ExecutionException -它不会“挂起”。您确定您的异常不是打印出来的,而是在日志或控制台输出中丢失的吗?

在跟踪您的代码时,我发现您的程序在读取完流后无法完成。也许正在读取错误流的进程仍在运行,而InputStream尚未关闭?可能有太多的输出,以至于您正在用StringBuffer填充核心(应该更改为StringBuilder )。

您是否可以使用j控制台附加到应用程序以查看线程是否仍在运行,如果仍在运行,则它在做什么?

代码语言:javascript
运行
复制
 if(future.get() == null) {
     log.info("Done completing error thread");
 }

因此,只有当从null方法返回call()时,这才会记录输出。这将永远不会发生,因为唯一的回报是return sb.length();。因此,要么您将从您的call()中得到一个异常,要么您的结果将是一个非空Integer

票数 2
EN

Stack Overflow用户

发布于 2013-09-17 22:24:20

来自Process javadoc:

由于一些本机平台只为标准输入和输出流提供有限的缓冲区大小,如果不及时写入输入流或读取子进程的输出流,可能会导致子进程阻塞,甚至导致死锁。

根据此警告,您的future.get()方法是挂起的,因为您只使用来自process对象的错误流。在我使用过Process对象的所有平台上,我注意到您需要同时使用错误流和标准输出流。

是一个很好的工具,它使用多线程方法来确保流程流被消耗。

在本例中,由于您似乎不关心流程的标准输出,所以可以使用StreamHelper类添加类似的内容:

代码语言:javascript
运行
复制
StreamHelper inStreamHelper = new StreamHelper(proc.getInputStream());
inStreamHelper.start();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18859040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档