一般我们使用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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestFile.java
主进程:
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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestRuntime.java
调用发现在指定目录下创建了文件,但是并没有在控制台输出信息。因为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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestRuntime.java
这里不知为何,在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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestFile.java
父进程修改:
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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestRuntime.java
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 }
E:\GitHub\tools\JavaEEDevelop\Lesson1_JavaSe_Demo1\src\org\zln\thread\TestProcessBuilder.java