在正常情况下我们可以用Project.waitfor()的返回值是否等于0的方法来判断java调用外部程序是Pass或者是Fail。

但是这个方法往往会被因进程堵塞而导致程序发生死锁,无法再继续执行外部程序。

因为本地的系统对标准输入和输出所提供的缓冲池有限,所以错误的对标准输出快速的写入和从标准输入快速的读入都有可能造成子进程死锁。问题的关键在缓冲区这个地方:可执行程序的标准输出比较多,而运行窗口的标准缓冲区不够大,所以发生阻塞。接着来分析缓冲区,当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitfor()这里。

但是在其中过程中真正起关键作用的缓冲区是getErrorStream()对应的那个缓冲区没有被清空,意思就是说其实只要及时读取标准错误流缓冲区的数据程序就不会被block。

原先的代码

//run bat file
Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath.replaceAll(" ", "\" \""));
int exitcode=project.waitFor();
//kill the process
project.destroy();
logger.info(exitcode);
//if the exitcode is 0, the RIA TEST is passed,else the RIA TEST is failed
if(exitcode==0){
logger.info("============ is Passed============");
}
else{
Boolean resultFlag=false;
logger.info("============ is Failed============");
Assert.assertTrue(bugID+"Failed",resultFlag);
}

修改后的代码:

增加两个线程来读取标准输出流和标准错误流

		try{
//run bat file
Process project = Runtime.getRuntime().exec("cmd.exe /c " + batpath.replaceAll(" ", "\" \""));
final InputStream br = project.getInputStream();
final InputStream br_error = project.getErrorStream();
//run 2 threads to read the standard InputStream and the ErrorStream to avoid the project.
//waitfor()method blocked
new Thread() {
public void run() {
BufferedReader br1 = new BufferedReader(new InputStreamReader(br));
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null){
logger.info("RIATest info: "+line1);
}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//run thread to read the standard ErrorStream
new Thread() {
public void run() {
BufferedReader br2 = new BufferedReader(new InputStreamReader(br_error));
try {
String line2 = null;
while ((line2 = br2.readLine()) != null) {
if (line2 != null){
logger.info("Error: "+line2);
}
}
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
br_error.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start(); try{ int exitcode=project.waitFor();
//kill the process
project.destroy();
logger.info(exitcode);
//if the exitcode is 0, the RIA TEST is passed,else the RIA TEST is failed
if(exitcode==0){
logger.info("============ is Passed============");
}
else{
Boolean resultFlag=false;
logger.info("============ is Failed============");
Assert.assertTrue(bugID+"Failed",resultFlag);
} }
catch(Throwable e){ e.printStackTrace(); } }
catch(IOException e){
e.printStackTrace();
try
{
project.getErrorStream().close();
project.getInputStream().close();
project.getOutputStream().close();
}
catch(Exception ee){}
}

关于JAVA Project.waitfor()死锁问题的更多相关文章

  1. java 代码执行cmd 返回值异常 (关于JAVA Project.waitfor()返回值是1)

    关于JAVA Project.waitfor()返回值是1   0条评论 Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project ...

  2. 关于JAVA Project.waitfor()返回值是1

    Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project=null.而去根目录下点击被调用的bat文件发现也可以被正确执行. 这时 ...

  3. java compiler level does not match the version of the installed java project facet 解决方案

    项目出现 java compiler level does not match the version of the installed java project facet 错误,一般是项目移植出现 ...

  4. java compiler level does not match the version of the installed java project facet

    Java compiler level does not match the version of the installed java project facet错误的解决 因工作的关系,Eclip ...

  5. export a java project to runable jar

    When a java project needs to be transfered to another machine, e.g. vps, we need to export it to a r ...

  6. Using Maven to generate a Java Project or Web project

    I often to generate a Java project or Web project with Eclipse tool. Well, I have no idea when I wan ...

  7. Java compiler level does not match the version of the installed Java project facet.(转)

    Java compiler level does not match解决方法 从别的地方导入一个项目的时候,经常会遇到eclipse/Myeclipse报Description  Resource P ...

  8. maven项目 Java compiler level does not match the version of the installed Java project facet

    因工作的关系,Eclipse开发的Java项目拷来拷去,有时候会报一个很奇怪的错误.明明源码一模一样,为什么项目复制到另一台机器上,就会报“java compiler level does not m ...

  9. Java compiler level does not match the version of the installed Java project facet.问题

    从同事那里拷贝过来的web项目,导入到eclipse中,出现Java compiler level does not match the version of the installed Java p ...

随机推荐

  1. <?php echo "我的第一段 PHP 脚本!"; ?>

    <!DOCTYPE html><html><body> <?phpecho "我的第一段 PHP 脚本!";?> </body ...

  2. [置顶] Java 8全面解析!不知道的来看看那!

    java8的面世惊动了不少业界人员,让我们一起来看看吧! 函数式接口 函数式接口是只定义了一个抽象方法的接口.Java 8引入了FunctionalInterface注解来表明一个接口打算成为一个函数 ...

  3. poj 3266 Cow School 分数规划

    这个题目难度非常大,首先对于老师的一种方案,应用分数规划的一般做法,求出所有的c=t-rate*p,如果没有选择的c值中的最大值比选择了的c值中的最小值大,那么这个解是可以改进的. 那么问题就转化成了 ...

  4. Study notes for B-tree and R-tree

    B-tree B-tree is a tree data structure that keeps data sorted and allows searches, sequential access ...

  5. Tesseract Ocr引擎

    Tesseract Ocr引擎 1.Tesseract介绍 tesseract 是一个google支持的开源ocr项目,其项目地址:https://github.com/tesseract-ocr/t ...

  6. MFC 窗口重绘问题

    在客户区画直线等图形时, 发现当其最小化或者其他窗口遮挡时,出现窗口重绘,而将原来绘制的图形删除,上网上搜索知道,绘制图形的代码必须放置在Ondraw函数中,才能避免重绘时图形消失(因为一直在响应WM ...

  7. Silverlight技术调查(2)——跨域访问

    原文 Silverlight技术调查(2)——跨域访问 此调查web容器采用的是Tomcat,若允许所有域访问,只需在webapps下的根应用ROOT中,加入配置文件:clientaccesspoli ...

  8. Inhouse interview(websense)

    1.Tell me about yourself? My name is xxx,i 'm from xxx. now , I am a postgratuation and my major sub ...

  9. 基于visual Studio2013解决面试题之0604O(1)时间复杂度删除链表节点

     题目

  10. Android下QQ空间查看大图特效

    近期在做一个项目,里面有一个功能是实现Android QQ好友动态里面的缩略图放大,查看大图的效果.用过都知道,这个特效非常赞的,没用过的下载个玩玩吧.我刚開始以为放大的那个大图是一个Activity ...