java Process对象
Process对象.waitFor()的阻塞问题
有时需要在程序中调用可执行程序或脚本命令:
1 | Process process = Runtime.getRuntime().exec(shPath); |
Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。
它的所有标准io(即stdin,stdout,stderr)操作都将通过三个流(getOutputStream(),getInputStream(),getErrorStream())重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流出现失败,当缓冲区满之后将无法继续写入数据,则可能导致子进程阻塞,最终造成阻塞在waifor()这里。
针对这种情况,解法是要清空getInputStream()和getErrorStream()这两个流。而且两个流的清空一定是异步的。
1 | static void drainInBackground(final InputStream is) { |
还有一种解法是用ProcessBuilder来创建Process对象,必须要使用ProcessBuilder的redirectErrorStream方法。redirectErrorStream方法设置为ture的时候,会将getInputStream(),getErrorStream()两个流合并,自动会清空流,无需自己处理。如果是false,getInputStream(),getErrorStream()两个流分开,就必须自己处理,程序如下:
1 | try { |