熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java調用外部程序技巧

2013-11-23 19:13:53  來源: Java核心技術 
    前些天使用Java調用外部程序的時候發現線程會堵塞在waitfor()方法
   
    調用方法如下
   
    Process process = RuntimegetRuntime()exec(cmd)
   
    processwaitfor()
   
    如果直接在Shell中調用這個程序程序會很快結束不會僵死
   
    為什麼會堵塞呢原因是當調用exec(cmd)後JVM會啟動一個子進程該進程會與JVM進程建立個管道連接標准輸入標准輸出和標准錯誤流假設該程序不斷在向標准輸出流和標准錯誤流寫數據而JVM不讀取數據會暫時緩沖在Linux的緩沖區緩沖區滿後該程序將無法繼續寫數據會僵死所以Java程序就會僵死在waitfor()永遠無法結束
   
    解決辦法就是增加兩個線程一個線程負責讀標准輸出流另一個負責讀標准錯誤流這樣子數據就不會積壓在緩沖區程序就能夠順利運行
   
    查看源代碼後還發現一個潛在的問題但程序執行到exec的時候JVM會使用管道占有個文件句柄但程序運行結束後這三個句柄並不會自動關閉這樣最終會導致javaioIOException: Too many open files所以就算外部程序的沒有輸出也必須關閉句柄
   
    Process process=null;
   
    try{
   
      process = RuntimegetRuntime()exec(cmd)
   
      processwaitfor()
   
    }cache{
   
      processgetOutputStream()close()
   
      processgetInputStream()close()
   
      processgetErrorStream()close()
   
    }
   
    我們發覺當調用close()方法後JVM並不會立即回收句柄具體的回收時間不確定另外如果不調用close()句柄也會被回收也可能發生Too many open files的錯誤根據這篇文章不同的垃圾收集器會選擇不同的回收策略所以最好還是要關閉
   
    總結
   
    如果外部程序有大量輸出需要啟動額外的線程來讀取標准輸出和標准錯誤流
   
    必須關閉三個句柄
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26495.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.