一般我們使用Java運行其他類中的方法的時候,無論是靜態調用還是動態調用,都是在當前的進程中執行的。也就是只有一個Java虛擬機實例在運行。有時候需要通過Java代碼啟動多個Java子進程,這樣做會消耗些資源,但是程序變得更穩定。因為新啟動的進程是在不同的虛擬機中運行的。
?
在Windows中,一個虛擬機就是一個
?
有兩種方式調用一個進程
1、System.exec
子進程:


1 package org.zln.thread; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 /** 7 * Created by coolkid on 2015/6/21 0021. 8 */ 9 public class TestFile { 10 public static void main(String[] args) { 11 try { 12 File file = new File("D:\\my.txt"); 13 file.createNewFile(); 14 System.out.println("被調用成功!"); 15 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 } 20 }
主進程:


1 package org.zln.thread; 2 3 import java.io.IOException; 4 5 /** 6 * Created by coolkid on 2015/6/21 0021. 7 */ 8 public class TestRuntime { 9 public static void main(String[] args) { 10 String rootPath = "E:\\GitHub\\tools\\JavaEEDevelop\\out\\production\\Lesson1_JavaSe_Demo1"; 11 String mainPath = "org.zln.thread.TestFile"; 12 String command = "java -classpath "+rootPath+" "+mainPath; 13 Runtime runtime = Runtime.getRuntime(); 14 try { 15 System.out.println(command); 16 runtime.exec(command); 17 18 } catch (IOException e) { 19 e.printStackTrace(); 20 } 21 } 22 }
調用發現在指定目錄下創建了文件,但是并沒有在控制臺輸出信息。因為TestFile子進程并沒有自己的控制臺,改進代碼


1 package org.zln.thread; 2 3 import java.io.*; 4 5 /** 6 * Created by coolkid on 2015/6/21 0021. 7 */ 8 public class TestRuntime { 9 public static void main(String[] args) { 10 String rootPath = "E:\\GitHub\\tools\\JavaEEDevelop\\out\\production\\Lesson1_JavaSe_Demo1"; 11 String mainPath = "org.zln.thread.TestFile"; 12 String command = "java -classpath "+rootPath+" "+mainPath; 13 Runtime runtime = Runtime.getRuntime(); 14 try { 15 System.out.println(command); 16 Process process = runtime.exec(command); 17 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream()))); 18 String line; 19 while ((line = bufferedReader.readLine())!=null){ 20 System.out.println("子進程輸出:"+line); 21 } 22 bufferedReader.close(); 23 } catch (IOException e) { 24 e.printStackTrace(); 25 } 26 } 27 }
這里不知為何,在IDE中運行,輸出的是亂碼,在控制臺運行則不是亂碼
?
既然父進程可以獲取到子進程的輸出,那么父進程如何發送消息給子進程呢?
子進程修改:


1 package org.zln.thread; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 8 /** 9 * Created by coolkid on 2015/6/21 0021. 10 */ 11 public class TestFile { 12 public static void main(String[] args) { 13 try { 14 File file = new File("D:\\my.txt"); 15 file.createNewFile(); 16 System.out.println("被調用成功!"); 17 18 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 19 System.out.println("父進程輸入信息:"+bufferedReader.readLine()); 20 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 } 25 }
父進程修改:


1 package org.zln.thread; 2 3 import java.io.*; 4 5 /** 6 * Created by coolkid on 2015/6/21 0021. 7 */ 8 public class TestRuntime { 9 public static void main(String[] args) { 10 String rootPath = "E:\\GitHub\\tools\\JavaEEDevelop\\out\\production\\Lesson1_JavaSe_Demo1"; 11 String mainPath = "org.zln.thread.TestFile"; 12 String command = "java -classpath "+rootPath+" "+mainPath; 13 Runtime runtime = Runtime.getRuntime(); 14 try { 15 System.out.println(command); 16 Process process = runtime.exec(command); 17 /*向子進程輸入*/ 18 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 19 bufferedWriter.write("Hello 子進程!"); 20 bufferedWriter.close();/*必須現在就關閉,否則無法向子進程輸入信息*/ 21 /*獲取子進程輸出*/ 22 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream()))); 23 String line; 24 while ((line = bufferedReader.readLine())!=null){ 25 System.out.println("子進程輸出:"+line); 26 } 27 bufferedReader.close(); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 }
?
2、使用ProcessBuilder建立子進程


1 package org.zln.thread; 2 3 import java.io.*; 4 5 /** 6 * Created by coolkid on 2015/6/21 0021. 7 */ 8 public class TestProcessBuilder { 9 public static void main(String[] args) throws IOException { 10 ProcessBuilder processBuilder = new ProcessBuilder("java","org.zln.thread.TestFile"); 11 /*設置工作目錄*/ 12 processBuilder.directory(new File("E:\\GitHub\\tools\\JavaEEDevelop\\out\\production\\Lesson1_JavaSe_Demo1")); 13 Process process = processBuilder.start(); 14 15 /*向子進程輸入*/ 16 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 17 bufferedWriter.write("Hello 子進程!"); 18 bufferedWriter.close();/*必須現在就關閉,否則無法向子進程輸入信息*/ 19 /*獲取子進程輸出*/ 20 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream()))); 21 String line; 22 while ((line = bufferedReader.readLine())!=null){ 23 System.out.println("子進程輸出:"+line); 24 } 25 bufferedReader.close(); 26 27 28 } 29 }
?