一般我們在Java中運行其它類中的方法時,無論是靜態(tài)調(diào)用,還是動態(tài)調(diào)用,都是在當前的進程中執(zhí)行的,也就是說,只有一個Java虛擬機實例在運行。而有的時候,我們需要通過Java代碼啟動多個Java子進程。這樣做雖然占用了一些系統(tǒng)資源,但會使程序更加穩(wěn)定,因為新啟動的程序是在不同的虛擬機進程中運行的,如果有一個進程發(fā)生異常,并不影響其它的子進程。
在Java中我們可以使用兩種方法來實現(xiàn)這種要求。最簡單的方法就是通過Runtime中的exec方法執(zhí)行Jjava classname。如果執(zhí)行成功,這個方法返回一個Process對象,如果執(zhí)行失敗,將拋出一個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("被調(diào)用成功!");
}
}
// 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運行程序后,發(fā)現(xiàn)在C盤多了個Test1.txt文件,但在控制臺中并未出現(xiàn)"被調(diào)用成功!"的輸出信息。因此可以斷定,Test已經(jīng)被執(zhí)行成功,但因為某種原因,Test的輸出信息未在Test_Exec的控制臺中輸出。這個原因也很簡單,因為使用exec建立的是Test_Exec的子進程,這個子進程并沒有自己的控制臺,因此,它并不會輸出任何信息。
如果要輸出子進程的輸出信息,可以通過Process中的getInputStream得到子進程的輸出流(在子進程中輸出,在父進程中就是輸入),然后將子進程中的輸出流從父進程的控制臺輸出。具體的實現(xiàn)代碼如下如示:
// 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方法來為子進程提供輸入信息(即由父進程向子進程輸入信息,而不是由控制臺輸入信息)。
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |