<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    Java的多進程運行模式分析

    本文為原創,如需轉載,請注明作者和出處,謝謝!

    本文曾發表于天極網:http://dev.yesky.com/284/2659284.shtml

        一般我們在java中運行其它類中的方法時,無論是靜態調用,還是動態調用,都是在當前的進程中執行的,也就是說,只有一個java虛擬機實例在運行。而有的時候,我們需要通過java代碼啟動多個java子進程。這樣做雖然占用了一些系統資源,但會使程序更加穩定,因為新啟動的程序是在不同的虛擬機進程中運行的,如果有一個進程發生異常,并不影響其它的子進程。

    在Java中我們可以使用兩種方法來實現這種要求。最簡單的方法就是通過Runtime中的exec方法執行java classname。如果執行成功,這個方法返回一個Process對象,如果執行失敗,將拋出一個IOException錯誤。下面讓我們來看一個簡單的例子。

    // Test1.java文件
    import java.io.*;
    public class Test
    {
    public static void main(String[] args)
    {
    FileOutputStream fOut 
    = new FileOutputStream("c:\\Test1.txt");
    fOut.close();
    System.out.println(
    "被調用成功!");
    }
    }

    // Test_Exec.java
    public class Test_Exec
    {
    public static void main(String[] args)
    {
    Runtime run 
    = Runtime.getRuntime();
    Process p 
    = run.exec("java test1");
    }
    }

    通過java Test_Exec運行程序后,發現在C盤多了個Test1.txt文件,但在控制臺中并未出現"被調用成功!"的輸出信息。因此可以斷定,Test已經被執行成功,但因為某種原因,Test的輸出信息未在Test_Exec的控制臺中輸出。這個原因也很簡單,因為使用exec建立的是Test_Exec 的子進程,這個子進程并沒有自己的控制臺,因此,它并不會輸出任何信息。

    如果要輸出子進程的輸出信息,可以通過Process中的getInputStream得到子進程的輸出流(在子進程中輸出,在父進程中就是輸入),然后將子進程中的輸出流從父進程的控制臺輸出。具體的實現代碼如下如示:

    // Test_Exec_Out.java
    import java.io.*;
    public class Test_Exec_Out
    {
    public static void main(String[] args)
    {
    Runtime run 
    = Runtime.getRuntime();
    Process p 
    = run.exec("java test1");
    BufferedInputStream in 
    = new BufferedInputStream(p.getInputStream());
    BufferedReader br 
    = new BufferedReader(new InputStreamReader(in));
    String s;
    while ((s = br.readLine()) != null)
    System.out.println(s);
    }
    }


    從上面的代碼可以看出,在Test_Exec_Out.java中通過按行讀取子進程的輸出信息,然后在Test_Exec_Out中按每行進行輸出。上面討論的是如何得到子進程的輸出信息。那么,除了輸出信息,還有輸入信息。既然子進程沒有自己的控制臺,那么輸入信息也得由父進程提供。我們可以通過 Process的getOutputStream方法來為子進程提供輸入信息(即由父進程向子進程輸入信息,而不是由控制臺輸入信息)。我們可以看看如下的代碼:

    // Test2.java文件
    import java.io.*;
    public class Test
    {
    public static void main(String[] args)
    {
    BufferedReader br 
    = new BufferedReader(new InputStreamReader(System.in));
    System.out.println(
    "由父進程輸入的信息:" + br.readLine());
    }
    }

    // Test_Exec_In.java
    import java.io.*;
    public class Test_Exec_In
    {
    public static void main(String[] args)
    {
    Runtime run 
    = Runtime.getRuntime();
    Process p 
    = run.exec("java test2");
    BufferedWriter bw 
    = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
    bw.write(
    "向子進程輸出信息");
    bw.flush();
    bw.close(); 
    // 必須得關閉流,否則無法向子進程中輸入信息
    // System.in.read();
     }
    }

    從以上代碼可以看出,Test1得到由Test_Exec_In發過來的信息,并將其輸出。當你不加bw.flash()和bw.close()時,信息將無法到達子進程,也就是說子進程進入阻塞狀態,但由于父進程已經退出了,因此,子進程也跟著退出了。如果要證明這一點,可以在最后加上 System.in.read(),然后通過任務管理器(在windows下)查看java進程,你會發現如果加上bw.flush()和 bw.close(),只有一個java進程存在,如果去掉它們,就有兩個java進程存在。這是因為,如果將信息傳給Test2,在得到信息后, Test2就退出了。在這里有一點需要說明一下,exec的執行是異步的,并不會因為執行的某個程序阻塞而停止執行下面的代碼。因此,可以在運行 test2后,仍可以執行下面的代碼。
    exec方法經過了多次的重載。上面使用的只是它的一種重載。它還可以將命令和參數分開,如exec("java.test2")可以寫成exec("java", "test2")。exec還可以通過指定的環境變量運行不同配置的java虛擬機。

    除了使用Runtime的exec方法建立子進程外,還可以通過ProcessBuilder建立子進程。ProcessBuilder的使用方法如下:

    // Test_Exec_Out.java
    import java.io.*;
    public class Test_Exec_Out
    {
    public static void main(String[] args)
    {
    ProcessBuilder pb 
    = new ProcessBuilder("java""test1");
    Process p 
    = pb.start();
    … …
    }
    }

    在建立子進程上,ProcessBuilder和Runtime類似,不同的ProcessBuilder使用start()方法啟動子進程,而Runtime使用exec方法啟動子進程。得到Process后,它們的操作就完全一樣的。

    ProcessBuilder和Runtime一樣,也可設置可執行文件的環境信息、工作目錄等。下面的例子描述了如何使用ProcessBuilder設置這些信息。

    ProcessBuilder pb = new ProcessBuilder("Command""arg2""arg2"''');
    // 設置環境變量
    Map<String, String> env = pb.environment();
    env.put(
    "key1""value1");
    env.remove(
    "key2");
    env.put(
    "key2", env.get("key1"+ "_test");
    pb.directory(
    "..\abcd"); // 設置工作目錄
    Process p = pb.start(); // 建立子進程




    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2008-05-10 19:02 銀河使者 閱讀(2978) 評論(1)  編輯  收藏 所屬分類: java 原創

    評論

    # re: Java的多進程運行模式分析[未登錄]  回復  更多評論   

    學習 http://www.dwww.cn
    2009-06-19 21:15 | hello java
    主站蜘蛛池模板: 亚洲国产精品丝袜在线观看| 国产成人精品免费视频大全五级 | 在线观看免费无码专区| 免费看一级做a爰片久久| 亚洲成a人片在线不卡一二三区| 国产h肉在线视频免费观看| 日日摸日日碰夜夜爽亚洲| AV片在线观看免费| 亚洲欧洲无码AV不卡在线| 久久精品免费一区二区喷潮| 亚洲熟伦熟女专区hd高清| 永久黄网站色视频免费观看| 婷婷亚洲综合五月天小说在线| 亚洲人成电影在线播放| 精品免费tv久久久久久久| 亚洲嫩模在线观看| 韩国亚洲伊人久久综合影院| 国产在线ts人妖免费视频| 高潮内射免费看片| 黄页免费的网站勿入免费直接进入| 亚洲国产成人91精品| 午夜免费福利在线| jizz免费观看| 亚洲第一永久在线观看| 日韩免费a级毛片无码a∨| 美女视频黄a视频全免费网站一区 美女视频黄a视频全免费网站色 | 亚洲尹人香蕉网在线视颅| 一级中文字幕乱码免费| 亚洲一区二区三区无码中文字幕| 亚洲人成77777在线观看网| 拔擦拔擦8x华人免费久久| 国产一级a毛一级a看免费人娇| 久久国产亚洲高清观看| 日本免费一区尤物| WWW免费视频在线观看播放| 亚洲成年人电影网站| 亚洲av高清在线观看一区二区 | 九九久久精品国产免费看小说| 亚洲v国产v天堂a无码久久| 波多野结衣免费一区视频| 中文字幕亚洲男人的天堂网络|