Java中RunTime类介绍
Runtime 类代表着Java程序的运行时环境,每个Java程序都有一个Runtime实例,该类会被自动创建,我们可以通过Runtime.getRuntime()
方法来获取当前程序的Runtime实例。
获取当前Jvm的内存信息
/*
* 获取当前jvm的内存信息,返回的值是 字节为单位
* */
public static void getFreeMemory() {
//获取可用内存
long value = Runtime.getRuntime().freeMemory();
System.out.println("可用内存为:"+value/1024/1024+"mb");
//获取jvm的总数量,该值会不断的变化
long totalMemory = Runtime.getRuntime().totalMemory();
System.out.println("全部内存为:"+totalMemory/1024/1024+"mb");
//获取jvm 可以最大使用的内存数量,如果没有被限制 返回 Long.MAX_VALUE;
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("可用最大内存为:"+maxMemory/1024/1024+"mb");
}
获取jvm可用的处理器核心的数量
一般可以和newFixedThreadPool一起使用
/*
* 获取jvm可用的处理器核心的数量
* */
public static void getAvailableProcessors() {
int value = Runtime.getRuntime().availableProcessors();
System.out.println(value);
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
}
执行系统命令
RunTime.getRuntime().exec()的构造方法
public Process exec(String command)-----在单独的进程中执行指定的字符串命令。
public Process exec(String [] cmdArray)---在单独的进程中执行指定命令和变量
public Process exec(String command, String [] envp)----在指定环境的独立进程中执行指定命令和变量
public Process exec(String [] cmdArray, String [] envp)----在指定环境的独立进程中执行指定的命令和变量
public Process exec(String command,String[] envp,File dir)----在有指定环境和工作目录的独立进程中执行指定的字符串命令
public Process exec(String[] cmdarray,String[] envp,File dir)----在指定环境和工作目录的独立进程中执行指定的命令和变量
Process的几种方法
1.destroy():杀掉子进程
2.exitValue():返回子进程的出口值,值 0 表示正常终止
3.getErrorStream():获取子进程的错误流
4.getInputStream():获取子进程的输入流
5.getOutputStream():获取子进程的输出流
6.waitFor():导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止。如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,根据惯例,0 表示正常终止
注意:在java中,调用runtime线程执行脚本是非常消耗资源的,所以切忌不要频繁使用!
在调用runtime去执行脚本的时候,其实就是JVM开了一个子线程去调用JVM所在系统的命令,其中开了三个通道:输入流、输出流、错误流,其中输出流就是子线程走调用的通道。
大家都知道,waitFor是等待子线程执行命令结束后才执行, 但是在runtime中,打开程序的命令如果不关闭,就不算子线程结束。比如以下代码。
private static Process p = null;
p = Runtime.getRuntime().exec("notepad.exe");
p.waitFor();
System.out.println("-------------------我被执行了-------------------");
以上代码中,打开windows中记事本。如果我们不手动关闭记事本,那么输出语句就不会被执行,这点是需要理解的。
process的阻塞

打开记事本
Runtime.getRuntime().exec("notepad.exe");
打开某个文件(不管是word还excel等等文件)
Runtime.getRuntime().exec("cmd /c start " + "\"\" \"" + path + "\"");
打开ie浏览器
Runtime.getRuntime().exec("C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE");
得到系统的环境变量
@Test
public void dirRuntimeProcess() throws IOException, InterruptedException {
Process process = Runtime.getRuntime().exec("cmd.exe /c echo %JAVA_HOME%");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String string = null;
while ((string = bufferedReader.readLine()) != null) {
System.out.println(string); // D:\Java\jdk\jdk1.8.0_152
}
process.waitFor();
System.out.println("return: " + process.exitValue()); // return: 0
}
得到java的版本号,这个和上述的不一样
@Test
public void getJavaVersion() {
try {
Process process = Runtime.getRuntime().exec("javac -version");
BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = br.readLine()) != null)
System.out.println(line); // javac 1.8.0_152
process.waitFor();
System.out.println("Process exitValue: " + process.exitValue());
} catch (Throwable t) {
t.printStackTrace();
}
}
执行外部命令得到的结果
@Test
public void execProgramC() {
try {
Process process = Runtime.getRuntime().exec("C:/Users/76801/Desktop/huhx.exe");
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = br.readLine()) != null)
System.out.println(line); // Hello World.
process.waitFor();
System.out.println("Process exitValue: " + process.exitValue());
} catch (Throwable t) {
t.printStackTrace();
}
}
huhx.c比较简单,就是打印一句话。
#include<stdio.h> void main() {
printf("Hello World.");
}
导出mysql脚本
@Test
public void execMysqldump() throws IOException, InterruptedException {
String execCommand = "cmd c/ D:/Java/mysqldump.exe -uhuhx -phuhx boot_learn > D:/bootlearn.sql";
System.out.println("exec command: " + execCommand);
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(execCommand);
StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "Error");
StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "Output");
errorGobbler.start();
outputGobbler.start();
p.waitFor();
System.out.println("successful." + p.exitValue());
}
上述也使用到了网上所说的读出窗口的标准输出缓冲区中的内容,仍旧没有解决Process的waitFor阻塞问题。下面是清空缓冲区的线程代码:
public class StreamGobbler extends Thread { InputStream is;
String type; public StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
} public void run() {
try (InputStreamReader isr = new InputStreamReader(is);) {
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (type.equals("Error")) {
System.out.println("Error :" + line);
} else {
System.out.println("Debug:" + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码的目标是导出mysql数据库的脚本。没有找到问题的解决方案,运行环境是win10,jdk1.8。
在JVM中增加一个关闭的钩子
阅读ElasticSearch的源码时,BootStrap类中调用了Runtime.getRuntime().addShutdownHook方法。接下来对java.lang包中的Runtime类的addShutdownHook方法进行说明。
这个方法的意思就是在JVM中增加一个关闭的钩子,当JVM关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,当系统执行完这些钩子后,JVM才会关闭。所以这些钩子可以在JVM关闭的时候进行内存清理、对象销毁等操作。
为了更清晰的说明,编写如下程序:
public class TestShutdownHook {
public static void main(String[] args) {
// thread1
Thread thread1 = new Thread() {
public void run() {
System.out.println("thread1");
}
}; // thread2
Thread thread2 = new Thread() {
public void run() {
System.out.println("thread2");
}
}; // shutdownThread
Thread shutdownThread = new Thread() {
public void run() {
System.out.println("shutdownThread");
}
}; Runtime.getRuntime().addShutdownHook(shutdownThread); thread1.start();
thread2.start();
}
}
输出结果:
thread1
thread2
shutdownThread
或
thread2
thread1
shutdownThread
无论是先打印thread1还是thread2,shutdownThread 线程都是最后执行的(因为这个线程是在JVM执行关闭前才会执行)。
关闭JVM程序
Runtime的exit表示的关闭JVM程序,但是不释放内存,举例:
System.exit(0);//表示正常程序的关闭,执行的是以下操作:
public static void exit(int status) {
Runtime.getRuntime().exit(status);
}
备注:如果是 0表示正常关闭,如果是非0表示异常关闭,如果想释放内存的话,用“dispose()”关闭当前程序,并释放资源。
System.exit()的内部实现也是Runtime.getRuntime().exit();
Java中RunTime类介绍的更多相关文章
- java中Runtime类和Process类的简单介绍
在java.lang包当中定义了一个Runtime类,在java中对于Runtime类的定义如下: Java code public class Runtime extends Object 每个 J ...
- java中Runtime类详细介绍
Runtime类描述了虚拟机一些信息.该类采用了单例设计模式,可以通过静态方法 getRuntime()获取Runtime类实例.下面演示了获取虚拟机的内存信息: package Main; publ ...
- java中Runtime类
一.概述 Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接. 一般不能实例化一个Runtime对象, ...
- Java中BigDecimal类介绍及用法
Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteger 类是 ...
- 浅析Java.lang.Runtime类
一.概述 Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接. 一般不能实例化一个Runtime对象, ...
- 深入研究java.lang.Runtime类【转】
转自:http://blog.csdn.net/lastsweetop/article/details/3961911 目录(?)[-] javalang 类 Runtime getRuntime e ...
- 【转】深入研究java.lang.Runtime类
一.概述 Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接. 一般不能实例化一个Runtime对象, ...
- 【JAVA零基础入门系列】Day11 Java中的类和对象
今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...
- Java中Optional类的使用
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
随机推荐
- jdbc分页
分页是一个被讲到烂掉的话题,今天我再拾起来踹几脚吧 (Hibernate的分页做得很好很强大,用的人都知道 ,这个就不用再说了) 1.为什么要分页? 首先是数据量太大会影响查询和传输的性能,关键 ...
- mormot解析天气预报JSON数据
mormot解析天气预报JSON数据 uses SynCommons; constjson2 = '{' + #13#10 +'"error":0,' + #13#10 +'&qu ...
- 【mybatis】mybatis动态order by 的问题, 注意 只需要把#{} 改成 ${} 即可
先说解决方案: 注意 只需要把#{} 改成 ${} 即可 再看 使用过程: Mapper.java List<IntegralGoods> findInUid(@Param(" ...
- Introducing ASP.NET Core: The New ASP.NET in Town!
The new version of ASP.NET is called ASP.NET Core (a.k.a ASP.NET 5) and it has the most significant ...
- pytest文档5-fixture之conftest.py
前言 前面一篇讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作,但这种是整个脚本全局生效的,如果我想实现以下场景: 用例1需要先登录,用例2不需要登录,用例3需要先登录. ...
- Python学习(四)数据结构(概要)
Python 数据结构 本章介绍 Python 主要的 built-type(内建数据类型),包括如下: Numeric types int float Text Sequence ...
- iOS开源项目:DYNavigationController
DYNavigationController是一个实现了左右滑动导航的项目. https://github.com/dyang/DYNavigationController 首先用之前的跟视图初始化D ...
- go语言基础之函数类型
1.函数类型 示例: package main import "fmt" func Add(a, b int) int { return a + b } func main() { ...
- Android -- 使用主题配置文件,去掉程序启动界面的短暂黑屏
关于黑屏 默认的情况下,程序启动时,会有一个黑屏的时期,原因是,首个activity会加载一些数据,比如初始化列表数据等. 去除步骤 1./res/values/styles.xml 在 Theme ...
- java对象的强引用,软引用,弱引用和虚引用
1.强引用 以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用.如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它.当内存空 间不足,Java虚拟机宁愿抛出Out ...