Java进程相关

  1. Process

Process

Java的Process进程,与线程不同,java的进程操作是极度依赖于操作系统的,通常我们在Java中有两种方式创建进程。

通过Runtime直接运行

Runtime.getRuntime().exec("...");

通过ProcessBuilder创建进程

ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("");
Process process = processBuilder.start();

相比与Runtime创建,通过ProcessBuilder创建提供了更加方便的子进程输出输入流读写,个人更加推荐使用第二种创建进程。

JVM本身运行的java程序也是一个系统进程,在windows系统上,通过java程序创建的外部进程并没有自己的输出终端,其输出终端依赖于java进程。

在Linux和Mac系统上创建的外部进程并不是其java进程的子进程。

若想让它拥有其自己的输出终端,在Windows系统下我们使用以分离模式的方式启动此进程。

try {
    Runtime.getRuntime().exec("cmd /c start ....");
} catch (IOException e) {
    e.printStackTrace();
}

==踩坑,下面遇到的问题只是个人见解==

若不使用分离模式,则可能会遇到这种场景。

当子进程的标准输出被Java的Process标准输入流获取到的时候,若在缓冲区未得到及时的读取,则可能会因为数据过多的问题填满缓冲区,而导致子进程卡死。

如我在使用Java创建了一个外部媒体播放进程,但没有及时处理其InputStream中的数据,会使得外部进程卡死。

其它解决方案:

使用ProcessBuilder创建外部进程,并启动一个单独的线程,及时读取进程标准输入流中的数据

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
     ProcessBuilder processBuilder = new ProcessBuilder();
                   processBuilder.command("...");
                   try {
                       processBuilder.redirectErrorStream(true);
                       Process process = processBuilder.start();
                       //保证连接到子进程的标准输出的标准输入流不被阻塞
                       InputStream inputStream = process.getInputStream();
                       while (inputStream.read() != -1){
                           //do nothing
                       }
                       process.destroy();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
        }
});
//启动独立线程,不断循环处理
t1.start();
//主线程继续工作..

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com

文章标题:Java进程相关

字数:525

本文作者:Os467

发布时间:2023-05-30, 21:41:33

最后更新:2023-05-30, 21:41:18

原始链接:https://os467.github.io/2023/05/30/Process/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏