Java调用外部程序技巧
来源:互联网 发布:微信相关软件 编辑:程序博客网 时间:2024/05/21 06:18
前些天使用Java调用外部程序的时候,发现线程会堵塞在waitfor()方法。
调用方法如下:
- Process process = Runtime.getRuntime().exec(cmd);
- process.waitfor();
如果直接在Shell中调用这个程序,程序会很快结束,不会僵死。
为什么会堵塞呢,原因是当调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立3个管道连接,标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取,数据会暂时缓冲在Linux的缓冲区,缓冲区满后该程序将无法继续写数据,会僵死,所以Java程序就会僵死在waitfor(),永远无法结束。
解决办法就是增加两个线程,一个线程负责读标准输出流,另一个负责读标准错误流,这样子数据就不会积压在缓冲区,程序就能够顺利运行。
查看源代码后,还发现一个潜在的问题。但程序执行到exec的时候,JVM会使用管道,占有3个文件句柄,但程序运行结束后,这三个句柄并不会自动关闭,这样最终会导致java.io.IOException: Too many open files。所以就算外部程序的没有输出,也必须关闭句柄:
- Process process=null;
- try{
- process = Runtime.getRuntime().exec(cmd);
- process.waitfor();
- }cache{
- process.getOutputStream().close();
- process.getInputStream().close();
- process.getErrorStream().close();
- }
我们发觉当调用close()方法后,JVM并不会立即回收句柄,具体的回收时间不确定。另外如果不调用close(),句柄也会被回收,也可能发生“Too many open files”的错误。根据这篇文章,不同的垃圾收集器会选择不同的回收策略。所以最好还是要关闭。
总结
1.如果外部程序有大量输出,需要启动额外的线程来读取标准输出和标准错误流
2.必须关闭三个句柄
另外编写了一个工具类来方便使用,本来两行代码确要写成这么长,有点小折腾了。感兴趣的可以在这里下载:
引自:http://www.yankay.com/java%E8%B0%83%E7%94%A8%E5%A4%96%E9%83%A8%E7%A8%8B%E5%BA%8F%E6%8A%80%E5%B7%A7/
- Java调用外部程序技巧
- Java调用外部程序技巧
- java调用外部程序
- Java调用外部程序
- Java调用外部程序
- java调用外部程序
- Java调用外部程序
- JAVA 调用外部程序
- Java调用外部程序
- Java 调用外部程序
- RCP编程技巧:如何调用外部程序?
- java调用外部程序执行
- java实现外部程序调用
- 使用Java调用外部程序
- Java调用外部程序命令
- Java调用外部程序解决方案
- java如何调用外部程序
- JAVA调用外部程序错误
- 不高兴的小明
- 哎,人生的选择题
- 值传递和引用传递
- SGU 549 - Dumbbells
- 第七周周报
- Java调用外部程序技巧
- ssh免密码登陆
- 多重继承与虚函数表的实现原理
- JSP_SESSION
- js时钟显示
- 为android-support-v4.jar打包源码
- timer的应用一:制作简单的进度灯
- 第八周周报
- Oracle处理oracle Blob字段