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

Java程序多进程运行模式的实例分析

阅读更多

       一般我们在java中运行其它类中的方法 时,无论是静态调用,还是动态调用,都是在当前的进程中执行的,也就是说,只有一个java虚拟机实例在运行。而有的时候,我们需要通过java代码启动 多个java子进程。这样做虽然占用了一些系统资源,但会使程序更加稳定,因为新启动的程序是在不同的虚拟机进程中运行的,如果有一个进程发生异常,并不 影响其它的子进程。

  在Java中我们可以使用两种方法来实现这种要求。最简单的方法就是通过 Runtime中的exec方法执行java classname。如果执行成功,这个方法返回一个Process对象,如果执行失败,将抛出一个IOException错误。下面让我们来看一个简单 的例子。

 

// Test1.java文件
import java.io.*;
public class Test
{
 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 Test
{
 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 pb = new ProcessBuilder("Command", "arg2", "arg2", ’’’);
// 设置环境变量
Map env = pb.environment();
env.put("key1", "value1");
env.remove("key2");
env.put("key2", env.get("key1") + "_test");
pb.directory("..\abcd"); // 设置工作目录
Process p = pb.start(); // 建立子进程 
 
分享到:
评论

相关推荐

    Java程序多进程运行模式的实例分析.pdf

    Java程序多进程运行模式的实例分析 Java程序多进程运行模式是指在Java程序中启动多个Java子进程,每个子进程运行在不同的虚拟机进程中,这样可以提高程序的稳定性,因为如果一个子进程发生异常,不会影响其他子进程...

    Java的多进程运行模式分析与编程[收集].pdf

    Java的多进程运行模式是指在一个Java程序中启动多个独立的Java子进程,每个子进程都有自己的Java虚拟机实例,从而实现程序的并发执行和隔离。这样的设计有助于提高系统的稳定性和可扩展性,因为即使其中一个进程崩溃...

    Java程序设计技巧与开发实例

    总之,“Java程序设计技巧与开发实例”这本书覆盖了Java编程的多个方面,从基础到高级,从理论到实践,为学习者提供了全面的学习路径。通过阅读和实践书中的例子,开发者不仅可以提升编程技巧,还能培养解决问题的...

    控制只可以运行单个进程

    而某些配置工具如果多进程运行,可能会导致配置文件的竞态条件,影响系统设置的正确性。因此,很多后台服务、计时任务等都采用单进程设计。 实现单进程的方法有很多种,这里以编程语言Java为例,可以使用以下策略:...

    程序只运行一个实例,并将前一个实例提到前台

    总的来说,这篇博客文章很可能会深入讲解如何在实际编程中应用单例模式,特别是如何结合进程通信机制,确保程序在有多个启动尝试时,只会有一个实例在前台运行。同时,通过提供的源码,读者能够学习到如何在不同编程...

    只能运行一个程序(包括多用户)

    在IT领域,有时我们需要确保某个程序在特定环境中只能运行一个实例,这通常涉及到进程管理和软件设计策略。"只能运行一个程序(包括多用户)"这个标题指出的核心问题是如何限制同一台计算机上的多个用户同时运行同一...

    java多线程设计模式详解

    为了更好地理解和应用这些模式,提供的源码详解文件“java多线程设计模式详解”将详细展示各种模式的实现细节,通过分析源码,读者可以深入掌握Java多线程编程的核心技巧。务必花时间仔细阅读和实践,这对于提升并发...

    Java范例开发大全(全书源程序)

    实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 关系运算符 13 实例7 逻辑...

    Java范例开发大全 (源程序)

     实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制转换 11  2.2 运算符 12  实例5...

    java范例开发大全

    实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...

    使用jmap分析Java程序性能问题

    ### 使用jmap分析Java程序性能问题 在Java开发与维护过程中,经常遇到与内存相关的性能问题及故障。这些问题包括但不限于内存泄漏、频繁的垃圾回收、内存溢出等,它们不仅影响程序的稳定运行,还可能导致服务中断。...

    JAVA上百实例源码以及开源项目源代码

    2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。...

    JVM监控实例数 windows监控 线程测试 单例模式下测试JVM实例是否一个

    在Java开发中,JVM(Java Virtual Machine)是运行所有Java程序的核心,它负责解析字节码并执行。为了确保应用程序高效稳定地运行,开发者需要对JVM进行监控,了解其内部状态,如内存使用、线程活动等。本文将探讨...

    JAVA小聊天程序

    【JAVA小聊天程序】是一个基于JAVA技术开发的简单聊天应用程序,它为初学者提供了一个很好的实践案例,展示了网络通信的基本...通过分析和运行这个程序,开发者不仅可以提升JAVA编程技能,也能深入了解网络通信的原理。

    java范例开发大全源代码

     实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制转换 11  2.2 运算符 12 ...

    java范例开发大全(pdf&源码)

    实例1 开发第一个Java程序 7 第2章 Java基础类型与运算符(教学视频:39分钟) 9 2.1 基础类型 9 实例2 自动提升 9 实例3 自动转换 10 实例4 常用基础类型之强制转换 11 2.2 运算符 12 实例5 算术运算符 12 实例6 ...

    Java实现操作系统实验之进程调度.zip

    1. **进程与线程**:在Java中,进程是程序的执行实例,而线程是进程内的执行流。在模拟进程调度时,需要理解这两个概念的区别,并用Java的`Thread`类或`Runnable`接口来创建线程。 2. **进程状态**:进程有新建、...

    程序设计语言C与Java之探讨.pdf

    本文探讨了程序设计语言C与Java的发展历史和应用,分析了它们的运行时模式,在面向对象的实例实现技术方面进行了对比,进而分析和比较了内存管理和垃圾回收机制。 程序设计语言的发展简史 软件必须依托硬件。在...

Global site tag (gtag.js) - Google Analytics