关于JAVA Project.waitfor()死锁问题
在正常情况下我们可以用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()死锁问题的更多相关文章
- java 代码执行cmd 返回值异常 (关于JAVA Project.waitfor()返回值是1)
关于JAVA Project.waitfor()返回值是1 0条评论 Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project ...
- 关于JAVA Project.waitfor()返回值是1
Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project=null.而去根目录下点击被调用的bat文件发现也可以被正确执行. 这时 ...
- 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 错误,一般是项目移植出现 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- maven项目 Java compiler level does not match the version of the installed Java project facet
因工作的关系,Eclipse开发的Java项目拷来拷去,有时候会报一个很奇怪的错误.明明源码一模一样,为什么项目复制到另一台机器上,就会报“java compiler level does not m ...
- 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 ...
随机推荐
- ubuntu 安装Opencv2.4.7
1.安装Cmake: sudo apt-get install cmake 2.到Opencv目录下创建文件夹release $ cmake -D CMAKE_BUILD_TYPE=RELEASE - ...
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克的显示
1.先定义坦克的一些属性 class Tank : public CCSprite { public : Tank(); ~Tank(); static Tank* createTankWithTan ...
- Use GraceNote SDK in iOS(二)获取音乐的完整信息
在需求彻底明朗化,外加从MusicFans转到GraceNote,再从GraceNote的GNSDK转到iOS SDK后,最终完毕了在iOS上通过音乐的部分信息获取完整信息的功能了.(好吧,我承认是相 ...
- shell语法简单介绍
一.基本的语法 1.1.shell文件开头 shell文件必须以以下的行開始(必须方在文件的第一行): #!/bin/sh 符号#!用来告诉系统它后面的參数是用来运行该文件的程序.在这个样例中我们 ...
- eclipse导入myeclipse的web项目没法识别问题解决方法
1.进入项目目录,找到.project文件,打开. 2.找到<natures>...</natures>代码段. 3.在第2步的代码段中加入如下标签内容并保存: <nat ...
- winform窗体全屏
bool fullscreen = false;Rectangle rect = new Rectangle();private void button4_Click(object sender, E ...
- 学习老外用webstorm开发nodejs的技巧--代码提示DefinitelyTyped
最近入了nodejs的坑,作为老码农,js对我来说还是很容易的.webstorm虽说用得不多,但是pycharms我是老手了,idea的东西一脉相承,想想也就那样了. 但是自从看了某个视频后,觉得毕竟 ...
- Android 事件处理
目的:通过全面的分析Android的鼠标和键盘事件.了解Android中如何接收和处理键盘和鼠标事件,以及如何用代码来产生事件. 主要学习内容: 1. 接收并处理鼠标事件:按下.弹起.移动.双击.长按 ...
- winform基础——数据访问及几个案例
数据访问分为三个部分:(1)创建链接(2)创建与执行命令(3)读取或准备相关数据 一,需要引用的命名空间 using data: using data.SqlClient; 二,创建与数据库的链接—— ...
- POJ2782:Bin Packing
Description A set of n<tex2html_verbatim_mark> 1-dimensional items have to be packed in iden ...