系統執行阻塞分析及解決方案

1.  背景

系統上線後,準備通過logQuery進行計算,並檢驗數據是否準確,但程序計算1w左右時停止。

2.  分析

系統運行原理

系統通過logQuery系統執行Runtime方法調用shell腳本啓動java補貨計算系統。

問題分析

         在系統死鎖時,通過jstack觀察jvm中所有線程運行情況和線程狀態。


發現有一個線程處於runnable狀態並locked了log4j的callAppenders方法和doAppend方法,由於callAppenders和doAppend中含有synchronized,所以導致其他線程死鎖。



         繼續進行測試及分析,發現直接運行shell腳本進行補貨計算沒有發生死鎖問題,所以可以排除shell腳步及計算程序問題。

         於是將問題集中到logQuery代碼中,通過大量的測試及百度搜索,最終將問題縮小到Runtime方法的Process返回類型中。

查看JAVA API:

大喜,問題估計找到了。

系統死鎖時代碼結構

串行運行,需要 errorBr流全部輸出完畢後,纔會輸出br流程中信息。可能會導致API中所描述的死鎖。

隨即寫了一個多線程進行測試。

注意:代碼後需要添加process.waitFor(),作用就是當前線程等待,直到所有子線程運行完畢。

至此補貨系統線程阻塞問題解決。

3.  關於Ant對Runntime方法的使用

下載ant-source-1.7.1,導入到eclipse中。

進入org.apache.tools.ant.taskdefs.Exec.java中,查看protectedint run(String command) 方法。

竊喜,跟當初解決方案一樣,都是多線程輸出getInputStream和getErrorStream兩個InputStream流。

不過值得注意的是:ant中使用了join及destroy,使代碼更加完善。

 

Exec.java在ant1.2之後已經廢棄不在維護,取而代之的是org.apache.tools.ant.taskdefs.Execute.java,Execute加強了對代碼的抽象性和擴展性,但對於本次分析,使用Exec.java更直觀易懂。

發佈了22 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章