首页 > 系统相关 >Java ProcessBuilder 启动的进程阻塞不退出问题。

Java ProcessBuilder 启动的进程阻塞不退出问题。

时间:2025-01-14 13:59:34浏览次数:1  
标签:Java ProcessBuilder stream process 阻塞 error output proc input

https://wiki.sei.cmu.edu/confluence/display/java/FIO07-J.+Do+not+let+external+processes+block+on+IO+buffers

 

java通过调用进程读取输出启动进程的标准输出时,如果被调用进程的,标准输出以及错误流的缓冲区被写满, 后续写入会导致调用进程会卡住,无法正常结束。 

确保waiffor之前读取清空了所有流数据,并在waitfor 之后 关闭流。 在waifor 之前关闭仍有可能卡住!

 

These processes may require input to be sent to their input stream, and they may also produce output on their output stream, their error stream, or both. Incorrect handling of such external programs can cause unexpected exceptions, denial of service (DoS), and other security problems.

A process that tries to read input on an empty input stream will block until input is supplied. Consequently, input must be supplied when invoking such a process.

Output from an external process can exhaust the available buffer reserved for its output or error stream. When this occurs, the Java program can block the external process as well, preventing any forward progress for both the Java program and the external process. Note that many platforms limit the buffer size available for output streams. Consequently, when invoking an external process, if the process sends any data to its output stream, the output stream must be emptied. Similarly, if the process sends any data to its error stream, the error stream must also be emptied.

 

合格的代码(合并错误流, 并完全读取)

public class Exec {
  public static void main(String args[])
                          throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder("notemaker");
    pb = pb.redirectErrorStream(true);
    Process proc = pb.start();
    InputStream is = proc.getInputStream();
    int c;
    while ((c = is.read()) != -1) {
      System.out.print((char) c);
    }
    int exitVal = proc.waitFor();
  }
}

合格的代码2 

class StreamGobbler implements Runnable {
  private final InputStream is;
  private final PrintStream os;
 
  StreamGobbler(InputStream is, PrintStream os) {
    this.is = is;
    this.os = os;
  }
 
  public void run() {
    try {
      int c;
      while ((c = is.read()) != -1)
          os.print((char) c);
    } catch (IOException x) {
      // Handle error
    }
  }
}
 
public class Exec {
  public static void main(String[] args)
    throws IOException, InterruptedException {
 
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec("notemaker");
 
    // Any error message?
    Thread errorGobbler
      = new Thread(new StreamGobbler(proc.getErrorStream(), System.err));
  
    // Any output?
    Thread outputGobbler
      = new Thread(new StreamGobbler(proc.getInputStream(), System.out));
 
    errorGobbler.start();
    outputGobbler.start();
 
    // Any error?
    int exitVal = proc.waitFor();
    errorGobbler.join();   // Handle condition where the
    outputGobbler.join();  // process ends before the threads finish
  }
}

 

标签:Java,ProcessBuilder,stream,process,阻塞,error,output,proc,input
From: https://www.cnblogs.com/uncleguo/p/18670624

相关文章

  • java集成开发环境快速配置
    1下载vscode2在插件店铺中搜索java,把开头几个包含java的插件全都安装好3新建文件test.java    并且把后面这个文件复制进去 importjava.util.concurrent.Executor;publicclasstest{publicstaticvoidmain(String[]args)throwsInterruptedExcept......
  • Executor建立线程示范代码java
    importjava.util.concurrent.Executor;publicclasstest{publicstaticvoidmain(String[]args)throwsInterruptedException{SubExecutorsubExecutor=newSubExecutor();subExecutor.execute(newTicketStation(200));subExecutor......
  • Java Dubbo 面试题
    谈谈你理解的Dubbo?Dubbo是一个高性能的JavaRPC框架,它提供了服务的注册、发现、调用以及监控等功能,使得开发者可以方便地构建分布式系统和服务化架构。服务治理:Dubbo提供了一套服务治理的解决方案,包括服务的注册、发现、负载均衡、容错和监控等。高性能:Dubbo支持多种协议,如Du......
  • Java高级开发工程师面试题3道
    面试题1:内存泄漏与垃圾回收机制问题:在最近的一个项目中,我们遇到了一个内存泄漏的问题。我们的应用程序运行一段时间后,JVM的堆空间使用率逐渐增加,直到最终触发了OutOfMemoryError错误。你能分析一下可能的原因,并给出解决办法吗?请用具体的例子来说明。回答:内存泄漏是指程......
  • JavaScript基础01
    一、基本情况#1、介绍JavaScript是一门解释性的脚本语言,主要用来给HTML网页增加动态功能。通常的js是运行在浏览器环境下的,可以帮助我们去控制页面,实现丰富的功能。会有dom和bom的api去操作html文档和浏览器的一些功能。nodejs是运行在计算机环境下的。语法一样,但是因为环......
  • Java学习,集合遍历
    Java遍历集合(如List, Set, Map等)通常有多种方法。遍历集合的方式,包括传统for循环、增强的for循环(也称"for-each"循环)、迭代器(Iterator)以及流(Stream)API。示例:for循环遍历List:List<String>list=Arrays.asList("Apple","Banana","Cherry");for(inti=0;i<......
  • Java学习,集合打乱顺序
    Java将一个集合中的元素顺序打乱,可以使用Collections类中的shuffle方法。这个方法是一个静态方法,它接受一个实现了List接口的集合作为参数,并使用一个默认的随机源对该集合进行随机排序,从而打乱元素的顺序。使用Collections类Collections.shuffle(),例1:importjava.util.*;......
  • 【JAVA 基础 第(18)课】HashSet 使用方法详解
    HashSet:Set接口的实现类,存放无序的,不可重复的元素判断是否为重复的对象比较hashCode()方法的返回值,如果不同,判定为不同的对象,如果相同,执行第二步判断equals()方法的返回值,如果为true,则判为相同的对象,如果为false,则为不同的对象publicclassHashSetTest{ publicstatic......
  • 【MSF代码审计】Java木源码分析
    免责声明由于传播、利用本文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,一旦造成后果请自行承担!很喜欢一位师傅说的话:"红队能有很多标准板和长板,但是不能有短板"。今天学习免杀,msf开源的可以分析代码,那就先来看看msf怎么写的吧开启分析之路1、......
  • Java基础
    数据类型强类型语言要求变量的使用要严恪符合规定,所有变量都必须先定义后才能使用,初始化(安全)而JavaScript是弱类型语言八大基本数据类型publicclassDemo02{publicstaticvoidmain(String[]args){//八大基本数据类型 //整数 intnum1=10;//最......