Process#waitFor()阻塞问题
有时需要在程序中调用可执行程序或脚本命令:
Process process = Runtime.getRuntime().exec(shPath);
int exitCode = process .waitFor();
Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。
它的所有标准io(即stdin,stdout,stderr)操作都将通过三个流(getOutputStream()
,getInputStream()
,getErrorStream()
)重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流出现失败,当缓冲区满之后将无法继续写入数据,则可能导致子进程阻塞,最终造成阻塞在waifor()
这里。
针对这种情况,解法是要清空getInputStream()
和getErrorStream()
这两个流。而且两个流的清空一定是异步的。
static void drainInBackground(final InputStream is) { new Thread(new Runnable(){ public void run(){ try{ while( is.read() >= 0 ); } catch(IOException e){ // return on IOException } } }).start(); }
还有一种解法是用ProcessBuilder来创建Process对象,必须要使用ProcessBuilder的redirectErrorStream
方法。redirectErrorStream方法设置为ture的时候,会将getInputStream()
,getErrorStream()
两个流合并,自动会清空流,无需自己处理。如果是false,getInputStream()
,getErrorStream()
两个流分开,就必须自己处理,程序如下:
try { ProcessBuilder pbuilder=new ProcessBuilder("ping","192.168.0.125"); pbuilder.redirectErrorStream(true); process=pbuilder.start(); reader=new BufferedReader(new InputStreamReader(process.getInputStream())); String line=null; while((line=reader.readLine())!=null){ System.out.println(line); } int result=process.waitFor(); System.out.println(result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }
Process process = null;try {process = launchProcess(cmdlist, environment);StringBuilder sb = new StringBuilder();String output = getOutput(process.getInputStream());String errorOutput = getOutput(process.getErrorStream());sb.append(output);sb.append("\n");sb.append(errorOutput);boolean ret = process.waitFor(1L, TimeUnit.SECONDS);if (!ret) {System.out.println(command + " is terminated abnormally. ret={}, str={}" + ret + " " + sb.toString());}return sb.toString();} catch (Throwable e) {System.out.println("Failed to run " + command + ", ");e.printStackTrace();} finally {if (null != process) {process.destroy();}}return "";
注意process一定要释放
Process#waitFor()阻塞问题相关推荐
- java Process.waitFor阻塞
关于java Process waitFor() 进程阻塞问题 摘录自:http://lelglin.iteye.com/blog/1487351 问题:有同学遇到java调用Process.exec ...
- Java Process.waitFor() 阻塞卡住不返回
1. 现象 在Java程序中,启动另一个进程执行一个命令时可以使用ProcessBuilder类启动一个进程. 以运行 ps 命令为例: ProcessBuilder processBuilder = ...
- 怎样判断子进程已经结束 process.waitFor();的问题
怎样判断子进程已经结束 process.waitFor();的问题 2009年07月31日 14:38 来源:普索网 发表于:2007-02-28 10:25:04 楼主 ProcessBuild.c ...
- 为Process.waitFor设置超时
2019独角兽企业重金招聘Python工程师标准>>> Java中在使用Runtime.getRuntime().exec(command)调用系统命令后 一般会调用Process. ...
- Java Process.exitValue Process.waitFor()
http://gohands.blogbus.com/logs/172834178.html Process.exitValue() 采用非阻塞的方式返回,如果没有立即拿到返回值,则抛出异常 Proc ...
- java process.waitfor();,正确的调用系统命令——为Process.waitFor设置超时以及其他 | 学步园...
Java中在阻塞调用系统命令的时候,一般是使用Runtime.getRuntime().exec(command)返回一个process对象,再调用Process.waitFor()来等待命令执行结束 ...
- java 使用Process调用exe程序 及 Process.waitFor() 死锁问题了解和解决
前言 最近在开发android的同时也在开发java ,碰到了需要使用java 程序调用exe的需求,这里我使用的 process 来调用的.该篇文章 读完需要8+分钟,文章类型为 小白入门类型,此处 ...
- java执行python返回null_[转]java调用python脚本以及通过Process.waitFor()直接调用python模块返回错误代码1的一种解决办法...
常见的java调用python脚本方式 通过jython提供的类库实现 通过Runtime.getRuntime()开启进程来执行脚本文件 通过jython提供的类库实现 通过jython实现的话,我 ...
- java process的waitfor()阻塞问题
http://blog.csdn.net/jimzhai/article/details/7864806 Runtime runtime = Runtime.getRuntime(); Process ...
最新文章
- java Collection-Map 之 TreeMap
- springmvc配置DispatcherServlet拦截url注意事项
- python处理csv数据-python 数据处理 对csv文件进行数据处理
- WinForm应用只运行一次
- 在html中超链接_HTML 超级链接详细讲解
- CV之NS之VGG16:基于预训练模型VGG16训练COCO的train2014数据集实现训练《神奈川冲浪里》风格配置yml文件
- mysql查看执行计划_如何查看MySQL的执行计划
- xavier初始化_深入解读xavier初始化(附源码)
- android 八核手机,八核手机
- DCMTK:Receiving Images from PACS using DCMSCU
- 20162303 实验五 网络编程与安全
- Windows、Linux、macOS 爆严重安全漏洞!
- 【操作系统】进程的异步性
- 大数据怎样帮助运维工程师实现无死角监控?
- 字符串匹配——C++使用Regex
- Xcode插件失效解决办法
- CentOS配置history记录每个用户执行过的命令
- PHP trim()的使用
- 学编程必看:10道逻辑思维测试题(附答案)
- 8086/8088,80286,80386的CPU寄存器