Java的Runtime、Process类介绍及Runtime.getRuntime().exec方法的使用及问题

本文深入探讨了Java中Runtime类的定义与应用,包括如何获取Runtime实例,执行外部命令,以及管理内存。同时,详细解析了Runtime.exec()方法的使用,并讨论了Process类的流获取方法可能导致的死锁问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Runtime的定义

Runtime类是单实例的,每个Java应用程序都有一个该类的实例,它允许应用程序和运行应用程序的环境进行交互。可使用getRuntime方法获取该类的实例。

2. 常用方法
方法作用
getRuntime():Runtime返回与当前Java应用程序关联的运行时对象。
exec(String):Process在单独的进程中执行指定的字符串命令的方法。该方法会返回一个Process的实例,该方法有许多的重载,参见jdk源码
freeMemory():long返回Java虚拟机中的可用内存量
totalMemory():long返回Java虚拟机中的内存总量
maxMemory():long返回Java虚拟机将尝试使用的最大内存量。
exit(int):void通过启动其关闭序列来终止当前运行的Java虚拟机。此方法永远不会正常返回。参数用作状态代码;按照惯例,非零状态代码表示*异常终止。System.exit(int)其实就是调用该方法执行的
3. Runtime.getRuntime().exec()方法详解

使用exec方法执行字符串命令并返回一个process对象,下图是一个简单的示例:
在这里插入图片描述
exitValue方法使用于返回子进程的退出值,但是方法不会阻塞,也就是说在调用该方法时如果子进程尚未终止则会抛出IllegalThreadStateException异常。
如果需要等待子进程执行完毕,在继续运行程序,可以使用process.waitFor()方法,该方法是一个阻塞方法,直到process的自己进程运行结束才会返回,0表示正常终止。
destroy()方法用于杀死子进程。
isAlive()返回子进程的存活状态。

4. process.waitFor()可能造成死锁问题

这里先解释一下Process类的3个流获取方法:

方法说明
getOutputStream() :OutputStream获取子进程输入的输出流
getInputStream() :InputStream这里是获取子进程输出的输入流
getErrorStream() :InputStream获取自己进程错误输出的输入流

这里可能解释的不够清楚,首先子进程是指我们使用exec方法执行的进程,以getInputStream()方法为例,子进程的输出对于我们程序的进程是输入,所有相对java程序而言是输入流。

继续,waitFor()这个方法往往会因为子进程的阻塞而导致我们的程序发生死锁。
因为本地的系统对标准输入和输出所提供的缓冲池有限,所以错误的对标准输出快速的写入和从标准输入快速的读入都有可能造成子进程死锁。问题的关键在缓冲区这个地方:可执行程序的标准输出比较多,而运行窗口的标准缓冲区不够大,所以发生阻塞。接着来分析缓冲区,当Runtime对象调用exec(cmd)后,JVM会启动一个子进程,该进程会与JVM进程建立三个管道连接:标准输入,标准输出和标准错误流。假设该程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waitFor()这里。

简单的修改程序:
在这里插入图片描述

参考:
JDK源码
https://www.cnblogs.com/mingforyou/p/3551199.html
https://www.cnblogs.com/xriverside/p/4362609.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值