五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Process的waitFor死鎖問題及解決辦法

2020-12-07 15:20 作者:編程大戰(zhàn)  | 我要投稿

一、問題再現(xiàn)

使用wkhtmltopdf插件做html轉(zhuǎn)換pdf,打印條碼標簽。

打印兩三張沒問題,打印多了程序就出現(xiàn)這種卡死的情況,等很久程序也沒有反應,也不報錯,后臺也沒有程序輸出。試了幾次都是這種情況。感覺程序一直在等待,于是懷疑是死鎖。

二、查找原因

經(jīng)過查找資料了解到:Process.waitFor可能導致死鎖?

因為本地的系統(tǒng)對標準輸入和輸出所提供的緩沖池有限,所以錯誤的對標準輸出快速的寫入和從標準輸入快速的讀入都有可能造成子進程死鎖。問題的關鍵在緩沖區(qū)這個地方:可執(zhí)行程序的標準輸出比較多,而運行窗口的標準緩沖區(qū)不夠大,所以發(fā)生阻塞。接著來分析緩沖區(qū),當Runtime對象調(diào)用exec(cmd)后,JVM會啟動一個子進程,該進程會與JVM進程建立三個管道連接:標準輸入,標準輸出和標準錯誤流。假設該程序不斷在向標準輸出流和標準錯誤流寫數(shù)據(jù),而JVM不讀取的話,當緩沖區(qū)滿之后將無法繼續(xù)寫入數(shù)據(jù),最終造成阻塞在waitfor()這里。

需要注意讀取程序的stdout和stderr都是阻塞的操作,這意味著必須在兩個線程里分別讀取,而不是在一個線程里一次讀取,否則還是有可能出現(xiàn)阻塞的情況:比如先讀取stdout再讀取stderr,如果程序的stderr輸出已經(jīng)填滿了緩沖區(qū),程序就會阻塞不繼續(xù)執(zhí)行,但是java線程又阻塞在讀取stdout上,只有stdout結(jié)束了才會去讀取stderr。結(jié)果就是互相等待著的過程中哦給你程序卡死了

1.?當我們使用Runtime.exec執(zhí)行命令時,JAVA的線程會創(chuàng)建一個子進程,用于執(zhí)行命令,而且子進程和JAVA線程會分別獨立運行。

2.?JAVA線程需要等待命令的執(zhí)行完成,對命令的日志和返回值進行處理,所以我們在JAVA線程中調(diào)用Process.waitFor掛起來等待子進程完成。

3.?子進程執(zhí)行時,不斷的打印日志信息,我們通過Process.getInputStream和Process.getErrorStream進行獲取正常輸出日志和錯誤日志進行處理。

4.?這個時候子進程不斷的向JAVA線程寫入數(shù)據(jù),而JAVA線程調(diào)用Process.waitFor后已經(jīng)阻塞掛起,而子進程在不斷的向JAVA線程進行寫入數(shù)據(jù),當我們的Process.getInputStream的buffer緩沖區(qū)被寫滿,而JAVA線程依然掛起并未消費buffer中的數(shù)據(jù),導致子進程無法繼續(xù)向buffer緩沖區(qū)中繼續(xù)寫入數(shù)據(jù),導致子進程也掛起。 5. 這個時候JAVA線程和子進程都處于掛起的狀態(tài),JAVA線程等待子進程的結(jié)束,子進程等待JAVA線程對buffer緩沖區(qū)中的數(shù)據(jù)進行消費。兩者在相互等待導致死鎖。

死鎖原理圖

三、解決方案

1.思路

既然是由于buffer緩沖區(qū)的數(shù)據(jù)沒有消費導致子進程掛起,那么我們從這里下手。

a. 消費buffer緩沖區(qū)中的數(shù)據(jù)

b. 當JAVA線程調(diào)用Process.waitFor后,線程會進行掛起,那我們就使用多線程進行消費數(shù)據(jù)。

2.正常流程圖


3.代碼實現(xiàn)

容易出現(xiàn)死鎖的舊代碼



Process的waitFor死鎖問題及解決辦法的評論 (共 條)

分享到微博請遵守國家法律
德保县| 泰州市| 拉萨市| 辛集市| 阿瓦提县| 靖安县| 和政县| 娱乐| 唐海县| 闽侯县| 桂林市| 新建县| 谷城县| 望奎县| 余江县| 郴州市| 建德市| 高密市| 沁阳市| 教育| 阳东县| 新巴尔虎右旗| 神农架林区| 嘉兴市| 固安县| 珠海市| 司法| 鹿泉市| 河源市| 杭锦旗| 巫溪县| 承德县| 蒙阴县| 开远市| 讷河市| 寿阳县| 长阳| 抚远县| 依兰县| 屏边| 凤台县|