最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決

 更新時(shí)間:2022年12月20日 09:05:42   作者:小肥羊沖沖沖  
在編寫(xiě)Java程序時(shí),有時(shí)候我們需要調(diào)用其他的諸如exe,shell這樣的程序或腳本,下面這篇文章主要給大家介紹了關(guān)于java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決的相關(guān)資料,需要的朋友可以參考下

前言

最近在開(kāi)發(fā)android的同時(shí)也在開(kāi)發(fā)java ,碰到了需要使用java 程序調(diào)用exe的需求,這里我使用的 process 來(lái)調(diào)用的。該篇文章 讀完需要8+分鐘,文章類(lèi)型為 小白入門(mén)類(lèi)型,此處主要記錄,方便以后學(xué)習(xí)補(bǔ)充… 如有不正確的地方還望海涵 及 指出….

文章參考

process參考

waitfor掛起解析

1. 使用process調(diào)用exe程序

ProcessBuilder pb = new ProcessBuilder("C:\\Debug\\TestRedis.exe", keyNmae);
pb.redirectErrorStream(true);
Process process = pb.start();
//可能導(dǎo)致進(jìn)程阻塞,甚至死鎖
int ret = process.waitFor();
System.out.println("return value:"+ret);
System.out.println(process.exitValue());
byte[] bytes = new byte[process.getInputStream().available()];
process.getInputStream().read(bytes);
System.out.println(new String(bytes));
// ProcessBuilder api 方法
public ProcessBuilder(String... command) {
        this.command = new ArrayList<>(command.length);
        for (String arg : command)
            this.command.add(arg);
    }

首先我們先使用 processBuilder 創(chuàng)建出該對(duì)象,該對(duì)象我這里暫時(shí)使用了第一個(gè)參數(shù)為 exe 文件的地址,第二個(gè)參數(shù)為傳遞參數(shù),是我需要傳給exe 的字符串。后邊主要就是打印 輸入流,獲取exe 輸出信息。其實(shí)到這里java 調(diào)用exe 就已經(jīng)完 了,但是后續(xù)開(kāi)發(fā)中遇到一種問(wèn)題,就是程序莫名死鎖,沒(méi)有響應(yīng),于是使用debug 跟進(jìn)代碼,發(fā)現(xiàn)程序走到 waitfor 代碼行的時(shí)候程序就出現(xiàn)了掛起的情況,于是google了一番,明白了其中的原因。

2. waitfor 問(wèn)題描述分析

1.主進(jìn)程中調(diào)用pb.start會(huì)創(chuàng)建一個(gè)子進(jìn)程,用于執(zhí)行shell /exe 腳本。子進(jìn)程創(chuàng)建后會(huì)和主進(jìn)程分別獨(dú)立運(yùn)行。

2. 因?yàn)橹鬟M(jìn)程需要等待腳本執(zhí)行完成,然后對(duì)腳本返回值或輸出進(jìn)行處理,所以這里主進(jìn)程調(diào)用Process.waitfor等待子進(jìn)程完成。

3. 子進(jìn)程執(zhí)行過(guò)程就是不斷的打印信息。主進(jìn)程中可以通過(guò)Process.getInputStream和Process.getErrorStream獲取并處理。

4. 這時(shí)候子進(jìn)程不斷向主進(jìn)程發(fā)生數(shù)據(jù),而主進(jìn)程調(diào)用Process.waitfor后已掛起。當(dāng)前子進(jìn)程和主進(jìn)程之間的緩沖區(qū)塞滿(mǎn)后,子進(jìn)程不能繼續(xù)寫(xiě)數(shù)據(jù),然后也會(huì)掛起。

5. 這樣子進(jìn)程等待主進(jìn)程讀取數(shù)據(jù),主進(jìn)程等待子進(jìn)程結(jié)束,兩個(gè)進(jìn)程相互等待,最終導(dǎo)致死鎖。

3. 死鎖問(wèn)題解決

基于上述分析,只要主進(jìn)程在waitfor之前,能不斷處理緩沖區(qū)中的數(shù)據(jù)就可以。因?yàn)?,我們可以再waitfor之前,單獨(dú)啟兩個(gè)額外的線(xiàn)程,分別用于處理InputStream和ErrorStream就可以

try {
            //獲取進(jìn)程的標(biāo)準(zhǔn)輸入流
            final InputStream is1 = process.getInputStream();
            //獲取進(jìn)城的錯(cuò)誤流
            final InputStream is2 = process.getErrorStream();
            //啟動(dòng)兩個(gè)線(xiàn)程,一個(gè)線(xiàn)程負(fù)責(zé)讀標(biāo)準(zhǔn)輸出流,另一個(gè)負(fù)責(zé)讀標(biāo)準(zhǔn)錯(cuò)誤流
            new Thread() {
                public void run() {
                    BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
                    try {
                        String line1 = null;
                        while ((line1 = br1.readLine()) != null) {
                            if (line1 != null){}
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    finally{
                        try {
                            is1.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            new Thread() {
                public void  run() {
                    BufferedReader br2 = new  BufferedReader(new  InputStreamReader(is2));
                    try {
                        String line2 = null ;
                        while ((line2 = br2.readLine()) !=  null ) {
                            if (line2 != null){}
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    finally{
                        try {
                            is2.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            //可能導(dǎo)致進(jìn)程阻塞,甚至死鎖
            int ret = process.waitFor();
            System.out.println("return value:"+ret);
            System.out.println(process.exitValue());
            logger.info("event:{}", "RunExeForWindows",process.exitValue());
            byte[] bytes = new byte[process.getInputStream().available()];
            process.getInputStream().read(bytes);
            System.out.println(new String(bytes));
            logger.info("event:{}", "RunExeForWindows",new String(bytes));
        }catch (Exception ex){
            ex.printStackTrace();
            try{
                process.getErrorStream().close();
                process.getInputStream().close();
                process.getOutputStream().close();
            }
            catch(Exception ee){}
        }

如此便可以將 waitfor死鎖問(wèn)題避開(kāi),看完這個(gè)問(wèn)題,總結(jié)一下,多看官方api注釋….其實(shí)官方已經(jīng)提示我們,如下 為 api注釋

Causes the current thread to wait, if necessary, until the
     * process represented by this {@code Process} object has
     * terminated.  This method returns immediately if the subprocess
     * has already terminated.  If the subprocess has not yet
     * terminated, the calling thread will be blocked until the
     * subprocess exits.
@return the exit value of the subprocess represented by this
     *         {@code Process} object.  By convention, the value
     *         {@code 0} indicates normal termination.
     * @throws InterruptedException if the current thread is
     *         {@linkplain Thread#interrupt() interrupted} by another
     *         thread while it is waiting, then the wait is ended and
     *         an {@link InterruptedException} is thrown.

如果需要,導(dǎo)致當(dāng)前線(xiàn)程等待,直到此{(lán)@code Process}對(duì)象表示的進(jìn)程具有終止 如果子進(jìn)程,此方法立即返回已經(jīng)終止。 如果子進(jìn)程還沒(méi)有終止后,調(diào)用線(xiàn)程將被阻塞,直到子進(jìn)程退出。

總結(jié)

到此這篇關(guān)于java使用Process調(diào)用exe程序及Process.waitFor()死鎖問(wèn)題解決的文章就介紹到這了,更多相關(guān)java用Process調(diào)用exe程序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java發(fā)送post方法詳解

    Java發(fā)送post方法詳解

    這篇文章主要介紹了Java發(fā)送post方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Spring MVC的web.xml配置詳解

    Spring MVC的web.xml配置詳解

    這篇文章主要介紹了Spring MVC的web.xml配置詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • java實(shí)現(xiàn)單機(jī)限流

    java實(shí)現(xiàn)單機(jī)限流

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)單機(jī)限流,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • springboot集成mybatisplus的方法

    springboot集成mybatisplus的方法

    這篇文章主要為大家詳細(xì)介紹了springboot集成mybatisplus的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Spring如何實(shí)現(xiàn)管理事務(wù)

    Spring如何實(shí)現(xiàn)管理事務(wù)

    Spring通過(guò)編程式事務(wù)和聲明式事務(wù)管理來(lái)控制事務(wù)的邊界和行為,聲明式事務(wù)管理通過(guò)@Transactional注解實(shí)現(xiàn),提供了豐富的配置選項(xiàng)來(lái)控制事務(wù)的行為,如傳播行為、隔離級(jí)別、超時(shí)時(shí)間和回滾規(guī)則
    2024-11-11
  • Java NIO Path接口和Files類(lèi)配合操作文件的實(shí)例

    Java NIO Path接口和Files類(lèi)配合操作文件的實(shí)例

    下面小編就為大家分享一篇Java NIO Path接口和Files類(lèi)配合操作文件的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • java控制臺(tái)版實(shí)現(xiàn)五子棋游戲

    java控制臺(tái)版實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了java控制臺(tái)版實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Sparsearray稀疏數(shù)組原理及實(shí)例詳解

    Sparsearray稀疏數(shù)組原理及實(shí)例詳解

    這篇文章主要介紹了Sparsearray稀疏數(shù)組原理及實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Java如何基于反射機(jī)制獲取不同的類(lèi)

    Java如何基于反射機(jī)制獲取不同的類(lèi)

    這篇文章主要介紹了Java如何基于反射機(jī)制獲取不同的類(lèi),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java String 對(duì)象(你真的了解了嗎)

    Java String 對(duì)象(你真的了解了嗎)

    這篇文章主要介紹了Java String 對(duì)象(你真的了解了嗎),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10

最新評(píng)論

万荣县| 门头沟区| 奇台县| 宜丰县| 温宿县| 如东县| 济阳县| 元朗区| 襄垣县| 汤原县| 庆元县| 东辽县| 垦利县| 什邡市| 杨浦区| 商南县| 镇沅| 蓬安县| 瑞金市| 喀喇沁旗| 青川县| 舟曲县| 万荣县| 镇沅| 岱山县| 乌拉特后旗| 临海市| 淮北市| 新乡县| 郁南县| 翁源县| 焦作市| 克拉玛依市| 泰来县| 南开区| 乌拉特前旗| 镇远县| 霍林郭勒市| 邻水| 深水埗区| 武义县|