国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Java的多進(jìn)程運(yùn)行模式分析

2019-11-18 15:25:40
字體:
供稿:網(wǎng)友

  一般我們在java中運(yùn)行其它類中的方法時,無論是靜態(tài)調(diào)用,還是動態(tài)調(diào)用,都是在當(dāng)前的進(jìn)程中執(zhí)行的,也就是說,只有一個java虛擬機(jī)實例在運(yùn)行。而有的時候,我們需要通過java代碼啟動多個java子進(jìn)程。這樣做雖然占用了一些系統(tǒng)資源,但會使程序更加穩(wěn)定,因為新啟動的程序是在不同的虛擬機(jī)進(jìn)程中運(yùn)行的,假如有一個進(jìn)程發(fā)生異常,并不影響其它的子進(jìn)程。

  在Java中我們可以使用兩種方法來實現(xiàn)這種要求。最簡單的方法就是通過Runtime中的exec方法執(zhí)行java 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運(yùn)行程序后,發(fā)現(xiàn)在C盤多了個Test1.txt文件,但在控制臺中并未出現(xiàn)"被調(diào)用成功!"的輸出信息。因此可以斷定,Test已經(jīng)被執(zhí)行成功,但因為某種原因,Test的輸出信息未在Test_Exec的控制臺中輸出。這個原因也很簡單,因為使用exec建立的是Test_Exec的子進(jìn)程,這個子進(jìn)程并沒有自己的控制臺,因此,它并不會輸出任何信息。

  假如要輸出子進(jìn)程的輸出信息,可以通過Process中的getInputStream得到子進(jìn)程的輸出流(在子進(jìn)程中輸出,在父進(jìn)程中就是輸入),然后將子進(jìn)程中的輸出流從父進(jìn)程的控制臺輸出。具體的實現(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中通過按行讀取子進(jìn)程的輸出信息,然后在Test_Exec_Out中按每行進(jìn)行輸出。 上面討論的是如何得到子進(jìn)程的輸出信息。那么,除了輸出信息,還有輸入信息。既然子進(jìn)程沒有自己的控制臺,那么輸入信息也得由父進(jìn)程提供。我們可以通過Process的getOutputStream方法來為子進(jìn)程提供輸入信息(即由父進(jìn)程向子進(jìn)程輸入信息,而不是由控制臺輸入信息)。我們可以看看如下的代碼:

// 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("由父進(jìn)程輸入的信息:" + 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("向子進(jìn)程輸出信息");
  bw.flush();
  bw.close(); // 必須得關(guān)閉流,否則無法向子進(jìn)程中輸入信息
  // System.in.read();
 }
}
  從以上代碼可以看出,Test1得到由Test_Exec_In發(fā)過來的信息,并將其輸出。當(dāng)你不加bw.Flash()和bw.close()時,信息將無法到達(dá)子進(jìn)程,也就是說子進(jìn)程進(jìn)入阻塞狀態(tài),但由于父進(jìn)程已經(jīng)退出了,因此,子進(jìn)程也跟著退出了。假如要證實這一點,可以在最后加上System.in.read(),然后通過任務(wù)治理器(在windows下)查看java進(jìn)程,你會發(fā)現(xiàn)假如加上bw.flush()和bw.close(),只有一個java進(jìn)程存在,假如去掉它們,就有兩個java進(jìn)程存在。這是因為,假如將信息傳給Test2,在得到信息后,Test2就退出了。在這里有一點需要說明一下,exec的執(zhí)行是異步的,并不會因為執(zhí)行的某個程序阻塞而停止執(zhí)行下面的代碼。因此,可以在運(yùn)行test2后,仍可以執(zhí)行下面的代碼。
exec方法經(jīng)過了多次的重載。上面使用的只是它的一種重載。它還可以將命令和參數(shù)分開,如exec("java.test2")可以寫成exec("java", "test2")。exec還可以通過指定的環(huán)境變量運(yùn)行不同配置的java虛擬機(jī)。

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



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 潼南县| 广昌县| 鄂伦春自治旗| 昌乐县| 格尔木市| 上杭县| 平遥县| 翼城县| 衡阳县| 右玉县| 岳阳县| 三亚市| 牟定县| 布尔津县| 钟祥市| 湄潭县| 仁化县| 八宿县| 洛隆县| 红安县| 海林市| 林芝县| 贵溪市| 乌兰县| 金平| 蚌埠市| 绵阳市| 阿克| 米林县| 西林县| 水城县| 板桥市| 赫章县| 富宁县| 澄迈县| 且末县| 根河市| 潼南县| 银川市| 韩城市| 伊吾县|