关于JAVA输入输出流造成的Runtime线程阻塞问题【新人笔记】
萌新最近搬磚遇到一個問題,上面讓我做一個dump文件的自動解析系統,至于解析的工具,準備用的是google的breakpad,項目部署環境是linux+jdk1.8。其他的無關緊要也就不談了。
一開始寫了一個demo放到測試機上面跑,最初代碼如下(只保留轉換相關的代碼,所以不可以運行):
import java.io.InputStreamReader;public class DumpAnalyseUtil {public static boolean analyseDumpFile(String stackPath, String dumpPath, String symPath, String logPath){boolean result = false;Process process = null;File stackFile = new File(stackPath);File dumpFile = new File(dumpPath);File symbolFile = new File(symPath);File logFile = new File(logPath);try{if (stackFile.exists() && dumpFile.exists() && symbolFile.exists()){String command = stackPath + " " + dumpPath + " " + symPath + " > " + logPath;System.out.println(command);Runtime.getRuntime().exec(command).waitFor();result = true;}}catch (Exception e){System.out.println("Dump File Analysis Error: " + e.getMessage());if (process != null){try{process.getErrorStream().close();process.getInputStream().close();process.getOutputStream().close();}catch (IOException ie){ie.printStackTrace();}}}return result;}public static void main(String[] args) {String stackPath = "/data/breakpad/src/processor/minidump_stackwalk";String dumpPath = "/data/dump/lalala.dmp";String symPath = "/data/symbols/";String logPath = "/data/symbols/123456.log";boolean result = analyseDumpFile(stackPath, dumpPath, symPath, logPath);System.out.println(result);} }在測試環境中運行這個demo的時候,程序跑到waitFor()方法那里就卡住不動了。。。
后來發現是自己的java基礎還是有些薄弱,java在執行runtime命令時,輸入流和錯誤流都會不斷地進入JVM的緩沖區(一般來說不會有輸出流,但是如果我們的命令和java程序有信息交互的話,比如需要我們通過程序輸入什么參數的時候,這時候也會產生一些輸出流進入緩沖區,但是這些輸出流應該很快就被讀取了,所以出現阻塞一般都是輸入流和錯誤流引起的)。如果我們不去將緩沖區的這些信息流讀出來的話,他們就會一直待在緩沖區,并最終將其填滿,造成runtime的阻塞。
知道了問題的所在,就好解決了。既然這些數據流不讀取就會淤積的話,讀出來就好了,于是有了改進第一版(只放了改進的那部分代碼):
Process exec = Runtime.getRuntime().exec(command);BufferedReader insertReader = new BufferedReader(new InputStreamReader(exec.getInputStream())); BufferedReader errorReader = new BufferedReader(new InputStreamReader(exec.getErrorStream()));exec.waitFor();還有一種方式,就是如果這個錯誤輸出流里面的信息對你來說沒有什么價值的話,可以利用ProcessBuilder的redirectErrorStream方法,來把錯誤流和輸入流整合到一起,一并讀出來:
ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder.redirectErrorStream(true); Process p = processBuilder.start(); InputStream is = p.getInputStream(); BufferedReader bs = new BufferedReader(new InputStreamReader(is));另外,如果你的輸入流信息非常多,比如拷貝文件的話,則可以單獨起一個線程來讀取輸入流中的信息:
(這一塊是參考了 望星辰大海 的博客中的代碼 點擊打開鏈接)
就不具體放出來了,有興趣可以點擊鏈接過去看一下。
總結
以上是生活随笔為你收集整理的关于JAVA输入输出流造成的Runtime线程阻塞问题【新人笔记】的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 各个版本eclipse官方下载地址
- 下一篇: 【java】爬虫之零基础利用postma
