记一次使用 Process 对象时遇到的问题
Java中提供一个Runtime.exec()方法,可以用来生成一个Process对象,然后在这个Process对象中执行脚本。
但今天发现执行后,一直没有输出,同时也没有报错,没有Process结束的迹象。
自行搜索后发现原因如下源自该网站:
主进程中调用Runtime.exec会创建一个子进程,用于执行shell脚本。子进程创建后会和主进程分别独立运行。
因为主进程需要等待脚本执行完成,然后对脚本返回值或输出进行处理,所以一般都是主进程调用Process.waitfor等待子进程完成。
但子进程执行过程就是不断的打印信息。注:主进程中可以通过Process.getInputStream和Process.getErrorStream获取并处理。
这时候子进程不断向主进程发送数据,而主进程调用Process.waitfor后已挂起。当子进程和主进程之间的缓冲区塞满后,子进程不能继续写数据,然后也会挂起。
这样子进程等待主进程读取数据,主进程等待子进程结束,两个进程相互等待,最终导致死锁。
解决方案:
开两个线程在waitfor()命令之前读出窗口的标准输出缓冲区和标准错误流的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| new Thread() { @Override public void run() { BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = null; try { while ((line = in.readLine()) != null) { log.info("datax执行的结果为: "+line); } } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start();
new Thread(){ @Override public void run() { BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); String line = null; StringBuilder result=new StringBuilder(); try { while((line = err.readLine()) != null) { result.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { try { err.close(); } catch (IOException e) { e.printStackTrace(); } } } }.start();
|