一般我们使用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 }