多线程 调用多线程的方法 Runtime与ProcessBuilder

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

时间: 2024-10-26 23:06:59

多线程 调用多线程的方法 Runtime与ProcessBuilder的相关文章

调用webservice客户端方法 runtime modeler error: Wrapper class ××× is not found. Have you run APT to generate them?

用wsimport生成webservice的客户端以后,调用客户端生成方法时总是出现 runtime modeler error: Wrapper class stardand.nrcms.ncking.com.Login is not found. Have you run APT to generate them?这个错误; 这个公司的接口我原来是做过的,现在不同的是,换了个地址,和原来的环境是一样的,jdk1.6.20,然后加入了myeclipse里边的jax-ws 2.1 Runtime

Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二部分将第一部分的示例进行扩展,展示了如何在python中调用多线程的C模块:第三部分扩展了第二部分,增加了在C模块的线程中回调python的演示. 本文所用的环境为:64位Win7 + python 3.4 x86 + vs2010 一.windows下的C语言多线程程序 windows下多线程编程

实现多线程的两种方法:继承Thread类或实现Runnable接口

实现多线程的两种方法:继承Thread类或实现Runnable接口 Java中实现多线程有两种方法:继承Thread类和实现Runnable接口,在程序开发中只要是多线程,我们一般都是实现Runnable接口,原因归结为一点:实现接口比继承类要好. 多线程的第一种实现方式:继承Thread类 步骤如下 创建一个继承Thread的类(假定为A),并重写Thread的run方法 构造一个A类对象,假定为aa 调用aa的start方法.(start方法是从Thread继承过来的) 具体例子如下 pac

2.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理

package com.bawei.multithread; //注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法 public class TemplateThread { //如果这个方法不想被子类或者别人随意改动[这样子类就不能覆写该方法了],这里方法就要设置为final方法 public final void println(String message){ System.out.println("###################

NDK使用技巧、多线程调用注意、ndk中的工具使用

//NDK 使用技巧和多线程调用注意 //http://www.ibm.com/search/csass/search/?q=ndk&sn=dw&lang=zh&cc=CN&en=utf&hpp=20&dws=cndw&lo=zh void demo(JNIEnv* env, jobject thiz) { //这JNI接口指针可以存储,但只在当前线程仍然是有效的. /* A JNI environment pointer (JNIEnv*) is

PHP中实现异步调用多线程程序代码

本文章详细的介绍了关于PHP中实现异步调用多线程方法,下面我们以给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送来讲述. 比如现在有一个场景,给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送 第一种解决方法: 代码如下: <?php $count=count($emailarr); for($i=0;$i<$count;$i ) { sendmail(.....);//发送邮件 } ?>              这段代码用户体

多线程调用生成主键流水号存储过程产生主键冲突问题解决方案

遇到开发多线程测试插入数据的时候发现主键冲突问题 问题具体描述如下: -------------------------------------------------------------- 调用Procedure_insert Procedure_insert Begin Call procedure(获取流水号) Insert into table values(流水号作为id,其他列); End 流水号存储过程: Update 统计表 统计字段+1 Update 统计表 最终流水号 s

C# Webbrowser 常用方法及多线程调用

设置控件的值 /// <summary> /// 根据ID,NAME双重判断并设置值 /// </summary> /// <param name="tagName"></param> /// <param name="id"></param> /// <param name="value"></param> private void SetTxt(s

【转】 Pro Android学习笔记(七一):HTTP服务(5):多线程调用HttpClient

目录(?)[-] 应用共享HttpClient对象的同步问题 创建共享HttpClient代码 创建共享对象 创建可共享的HttpClient对象 使用共享HttpClient对象的代码 基础代码 修改HTTP连接的参数 使用共同的Appcliation对象 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 应用共享HttpClient对象的同步问题 在之前的例子中,HttpClient只