最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

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

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

2020-12-08 11:36 作者:每天一個禿頂小技巧  | 我要投稿

一、問題再現(xiàn)
使用wkhtmltopdf插件做html轉(zhuǎn)換pdf,打印條碼標簽。
打印兩三張沒問題,打印多了程序就出現(xiàn)這種卡死的情況,等很久程序也沒有反應(yīng),也不報錯,后臺也沒有程序輸出。試了幾次都是這種情況。感覺程序一直在等待,于是懷疑是死鎖。



二、查找原因
經(jīng)過查找資料了解到:Process.waitFor可能導致死鎖?
因為本地的系統(tǒng)對標準輸入和輸出所提供的緩沖池有限,所以錯誤的對標準輸出快速的寫入和從標準輸入快速的讀入都有可能造成子進程死鎖。問題的關(guān)鍵在緩沖區(qū)這個地方:可執(zhí)行程序的標準輸出比較多,而運行窗口的標準緩沖區(qū)不夠大,所以發(fā)生阻塞。接著來分析緩沖區(qū),當Runtime對象調(diào)用exec(cmd)后,JVM會啟動一個子進程,該進程會與JVM進程建立三個管道連接:標準輸入,標準輸出和標準錯誤流。假設(shè)該程序不斷在向標準輸出流和標準錯誤流寫數(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)死鎖的舊代碼

解決死鎖后的代碼:

文章摘自網(wǎng)絡(luò),侵刪

想要了解更多可以點擊:

尚學堂最新2020版Java300集教程課程

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

分享到微博請遵守國家法律
宝丰县| 潮州市| 兴业县| 博湖县| 庆城县| 巴中市| 信宜市| 连江县| 南通市| 观塘区| 遂溪县| 西安市| 兰考县| 泗阳县| 阿拉尔市| 醴陵市| 吴川市| 易门县| 遂川县| 靖州| 济宁市| 延边| 云霄县| 堆龙德庆县| 唐河县| 阜新| 天长市| 罗平县| 沧州市| 中西区| 吴忠市| 朝阳县| 昂仁县| 交城县| 洪雅县| 固阳县| 双柏县| 久治县| 本溪| 沐川县| 思南县|