`
aaron_ch
  • 浏览: 178113 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Java Multiple process (PID)

    博客分类:
  • Java
阅读更多

Java的多进程运行模式分析

一般我们在java中运行其它类中的方法时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个java虚拟机实例在运行。而有的时候,我们需要通过java代码启动多个java子进程。这样做虽然占用了一些系统资源,但会使程序更加稳定,因为新启动的程序是在不同的虚拟机进程中运行的,如果有一个进程发生异常,并不影响其它的子进程。
在Java中我们可以使用两种方法来实现这种要求。最简单的方法就是通过Runtime中的exec方法执行java classname。如果执行成功,这个方法返回一个Process对象,如果执行失败,将抛出一个IOException错误。下面让我们来看一个简单的例子。
// Test1.java文件

  import java.io.*;

  public class Test1 {
  public static void main(String[] args) {
  FileOutputStream fOut = new FileOutputStream("c:\\Test1.txt");
  fOut.close();
  System.out.println("被调用成功!");
  }
  }

  // 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运行程序后,发现在C盘多了个Test1.txt文件,但在控制台中并未出现"被调用成功!"的输出信息。因此可以断定,Test已经被执行成功,但因为某种原因,Test的输出信息未在Test_Exec的控制台中输出。这个原因也很简单,因为使用exec建立的是Test_Exec的子进程,这个子进程并没有自己的控制台,因此,它并不会输出任何信息。
如果要输出子进程的输出信息,可以通过Process中的getInputStream得到子进程的输出流(在子进程中输出,在父进程中就是输入),然后将子进程中的输出流从父进程的控制台输出。具体的实现代码如下如示:
  // 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中通过按行读取子进程的输出信息,然后在Test_Exec_Out中按每行进行输出。 上面讨论的是如何得到子进程的输出信息。那么,除了输出信息,还有输入信息。既然子进程没有自己的控制台,那么输入信息也得由父进程提供。我们可以通过Process的getOutputStream方法来为子进程提供输入信息(即由父进程向子进程输入信息,而不是由控制台输入信息)。我们可以看看如下的代码:
  // Test2.java文件
  import java.io.*;
  public class Test2{
  public static void main(String[] args) {
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  System.out.println("由父进程输入的信息:" + 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("向子进程输出信息");
  bw.flush();
  bw.close(); // 必须得关闭流,否则无法向子进程中输入信息
  // System.in.read();
  }
  }
  从以上代码可以看出,Test1得到由Test_Exec_In发过来的信息,并将其输出。当你不加bw.flash()和bw.close()时,信息将无法到达子进程,也就是说子进程进入阻塞状态,但由于父进程已经退出了,因此,子进程也跟着退出了。如果要证明这一点,可以在最后加上System.in.read(),然后通过任务管理器(在windows下)查看java进程,你会发现如果加上bw.flush()和bw.close(),只有一个java进程存在,如果去掉它们,就有两个java进程存在。这是因为,如果将信息传给Test2,在得到信息后,Test2就退出了。在这里有一点需要说明一下,exec的执行是异步的,并不会因为执行的某个程序阻塞而停止执行下面的代码。因此,可以在运行test2后,仍可以执行下面的代码。
  exec方法经过了多次的重载。上面使用的只是它的一种重载。它还可以将命令和参数分开,如exec("java.test2")可以写成exec("java", "test2")。exec还可以通过指定的环境变量运行不同配置的java虚拟机。
  除了使用Runtime的exec方法建立子进程外,还可以通过ProcessBuilder建立子进程。ProcessBuilder的使用方法如下:
  // Test_Exec_Out.java
  import java.io.*;
  public class Test_Exec_Out {
  public static void main(String[] args) {
  ProcessBuilder pb = new ProcessBuilder("java", "test1");
  Process p = pb.start();
  … …
  }
  }
  在建立子进程上,ProcessBuilder和Runtime类似,不同的ProcessBuilder使用start()方法启动子进程,而Runtime使用exec方法启动子进程。得到Process后,它们的操作就完全一样的。
  ProcessBuilder和Runtime一样,也可设置可执行文件的环境信息、工作目录等。下面的例子描述了如何使用ProcessBuilder设置这些信息。
  ProcessBuilder pb = new ProcessBuilder("Command", "arg2", "arg2", ''');
  // 设置环境变量
  Map< String, String > env = pb.environment();
  env.put("key1", "value1");
  env.remove("key2");
  env.put("key2", env.get("key1") + "_test");
  pb.directory("..\abcd"); // 设置工作目录
  Process p = pb.start(); // 建立子进程

 

分享到:
评论

相关推荐

    AHP Analytic Hierarchy Process (EVM multiple inputs)

    AHP Analytic Hierarchy Process (EVM multiple inputs)

    SAP PO/PI教程 Process Orchestration The Comprehensive Guide

    6.5 Supporting Multiple Senders for Your iFlow 6.6 Exercise: Building an Integration Flow 6.6.1 Exercise Description 6.6.2 Exercise Solution Approach 6.6.3 Exercise Step-by-Step Solution 6.7 ...

    GA.rar_PID参数 simulink_SIMULINK GA PID_m文件调用模型_pid tune_遗传算法 pi

    标题中的“GA.rar_PID参数 simulink_SIMULINK GA PID_m文件调用模型_pid tune_遗传算法 pi”揭示了本主题的核心内容,这是一个关于利用遗传算法(GA)优化PID控制器参数的工程实例。在这个过程中,我们将深入探讨...

    MDTEditor_v1.0 (java 多文档文本编辑器--Multiple Documents Text Editor)

    多文档文本编辑器--Multiple Documents Text Editor 使用java语言按照java Bean 规范进行开发,基于MVC模型, 编码规范简洁,结构紧凑,且有详细注释,很适用于java初学者 作为进阶的参考! 该软件实现了多文档编辑...

    一次性选择多文件上传multiple属性

    `name="files[]"` 的设定使得在服务器端(例如Java JSP)可以通过数组形式访问上传的文件。 然而,对于不支持`multiple`属性的浏览器,如IE9及以下版本,开发者需要采用其他策略来实现多文件上传。一种常见的方法是...

    Java Multiple Audio Format Converter-开源

    Java多音频格式转换器是一个基于Java的开源项目,它的主要功能是帮助用户将不同类型的音频文件转换为其他格式。这个工具特别适用于那些需要处理多种音频格式的用户,比如音乐爱好者、音频编辑人员或是开发者。其核心...

    java7帮助文档

    Java Platform Standard Edition 7 Documentation What's New Documentation Release Notes Tutorials and Training The Java Tutorials Java Training More Information Java SE 7 Names and ...

    Multiple Terrain Brush 1.5

    Multiple Terrain Brush is an editor tool with brushes for heightmaps and textures that work on multiple terrains. You can easily paint heightmap and textures, without switching from terrain to terrain...

    multiple-Select.js

    多选框要用到的js multiple-Select.js 用的时候引用到文件中

    Multiple Data Visualization Resources 中控大屏可视化插件

    《中控大屏可视化插件:Multiple Data Visualization Resources》 在现代数据分析与展示领域,数据可视化扮演着至关重要的角色。"Multiple Data Visualization Resources" 提供的 "Multiple_Graph_And_Chart_UI_...

    Keras Multiple outputs and multiple losses.zip

    在"Keras Multiple outputs and multiple losses"中,我们将看到如何构建一个能够处理不同任务的神经网络模型。例如,这可以是图像分类和对象定位,或者预测连续变量和分类变量。关键在于设计网络结构以并行地处理...

    Java访问Domino的编程指南.doc

    Java 访问 Domino 的编程指南...同时,Java 访问 Domino 对象需要经历预备步骤、JDK 及 IDE、API 及 访问协议、示例代码、参数定义、通过 IIOP 测试连接、通过 IOR 测试连接、连接池、读取 Domino 数等 Multiple 步骤。

    CADworx_PID操作说明

    More Tools: Multiple Edit and Block Editor - 更多工具:批量编辑和块编辑 - **批量编辑**:提供批量编辑功能,可以同时修改多个对象的属性,节省时间。 - **块编辑**:支持块编辑功能,可以轻松地编辑复杂的重复...

    synchronization-with-multiple-process

    synchronization-with-multiple-process

    java错误提示英汉对照

    - **Process进程**:指正在运行中的程序实例,每个进程都有自己的独立内存空间。 - **Thread绪程/线程**:是进程中的执行单元,线程共享进程的内存空间。 ##### - 其他术语 - **Polymorphism多型**:面向对象编程中...

    Multiple Span Cell Table

    在Java编程环境中,Swing库提供了丰富的组件用于创建图形用户界面(GUI)。"Multiple Span Cell Table" 是一个自定义的JTable实现,它扩展了Swing的默认功能,特别是增加了表格中单元格的多行多列合并能力。JTable是...

    multiple-select-master

    当我们需要在下拉列表中允许用户选择多个选项时,可以使用 `multiple` 属性。标题 "multiple-select-master" 提到的就是这个功能,即在 `select` 元素中启用多选模式。下面将详细讲解 `multiple` 属性的使用方法、...

    Java Projects

    Separate the wiring of multiple modules from application logic Use Java annotations for configuration Master the scripting API built into the Java language Understand static versus dynamic ...

Global site tag (gtag.js) - Google Analytics