背景
学习gRPC时,下载了官方的examples,在服务端类中发现了如下的一段代码:
private void start() throws IOException {
/* The port on which the server should run */
int port = 50051;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
System.err.println("*** shutting down gRPC server since JVM is shutting down");
try {
HelloWorldServer.this.stop();
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
System.err.println("*** server shut down");
}
});
}
点进去源码之后,发现了下面的一段话 :
Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.
An application cannot create its own instance of this class.
每一个java应用都有唯一的的RunTime实例,他允许与当前运行的环境进行交互,它只能通过getRuntime方法去创建,应用程序无法自己创建实例。 简单来说就是我们可以通过这个实例实现与操作系统进行交互,但是我们只能通过getRuntime()方法获取该实例。
Runtime中常用的方法
方法 | 参数 | 返回值 | 备注 |
---|---|---|---|
addShutdownHook(Thread hook) | 一个初始化但未启动的 Thread对象 | void | 注册一个新的虚拟机关机挂钩 |
availableProcessors() | 无 | void | 返回可用于Java虚拟机的处理器数量。 |
exec(String command) | command - 指定的系统命令。 | Process | 在单独的进程中执行指定的字符串命令。 |
exec(String[] cmdarray) | 包含调用命令及其参数的数组 | Process | |
exec(String[] cmdarray, String[] envp, File dir) | cmdarray - 包含调用命令及其参数的数组。 envp -串,其中每个元素的格式 名 = 值具有环境变量的设置,或 null如果子进程应该继承当前进程的环境的数组。 dir - dir的工作目录,或 null如果子进程应该继承当前进程的工作目录。 | Process | 在指定的环境和工作目录的单独进程中执行指定的命令和参数。 |
exit(int status) | status - 终止状态。 按照惯例,非零状态码表示异常终止。 | void | 通过启动其关闭序列来终止当前正在运行的Java虚拟机。 |
freeMemory() | 无 | long | 返回Java虚拟机中的可用内存量。 调用gc方法可能会导致增加返回的值freeMemory. |
maxMemory | 无 | long | 返回Java虚拟机将尝试使用的最大内存量。 如果没有固有的限制,则返回值Long.MAX_VALUE 。 |
totalMemory() | 无 | long | 返回Java虚拟机中的内存总量。 此方法返回的值可能随时间而变化,具体取决于主机环境。 |
gc() | 无 | 无 | 运行垃圾回收器。相当于System.gc() |
getRuntime() | 无 | Runtime | 返回与当前Java应用程序关联的运行时对象 |
halt(int status) | status - 终止状态。 按照惯例,非零状态码表示异常终止。 如果exit (等效地, System.exit )方法已被调用,则该状态代码将覆盖传递给该方法的状态代码。 | 无 | 强制终止当前正在运行的Java虚拟机。 此方法从不正常返回。 这种方法应该非常小心。 与exit方法不同,此方法不会导致关闭挂钩启动,如果已启用终止退出,则不会运行未受攻击的终结器。 如果关闭序列已经被启动,则该方法不等待任何运行的关闭挂钩或终结器完成其工作。 |
load(String filename) | filename - 要加载的文件。 | 无 | 加载由filename参数指定的本机库。 filename参数必须是绝对路径名。 (例如Runtime.getRuntime().load("/home/avh/lib/libX11.so"); )。 如果文件名参数在剥离任何特定于平台的库前缀,路径和文件扩展名时,表示名称为例如L的库,并且名为L的本地库与VM静态链接,则JNI_OnLoad_L函数调用库导出而不是尝试加载动态库。 与参数匹配的文件名不必存在于文件系统中。 有关详细信息,请参阅JNI规范。 否则,文件名参数以实现相关的方式映射到本机库映像。 |
使用场景
1.查询内存使用情况
public static void getMemory() {
System.out.println("total-memory:" + Runtime.getRuntime().totalMemory() / 1024 / 1024);
System.out.println("max-memory:" + Runtime.getRuntime().maxMemory() / 1024 / 1024);
System.out.println("free-memory:" + Runtime.getRuntime().freeMemory() / 1024 / 1024);
}
2.查询系统文件夹内容
public static void getDir() {
Process process;
//需要指定参数一:命令位置;参数二:/c表示先执行第一个参数;参数三:你的命令。
String[] cmd = {"cmd", "/C", "cd / && dir "};
try {
//执行命令
process = Runtime.getRuntime().exec(cmd);
//取得命令结果的输出流
InputStream inputStream = process.getInputStream();
//用一个读输出流类去读
InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("GBK"));
//用缓冲器读行
BufferedReader br = new BufferedReader(isr);
String line = null;
//结果输出流
//直到读完为止
System.out.println("输出");
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//输出流
InputStream errorStream = process.getErrorStream();
InputStreamReader error = new InputStreamReader(errorStream, Charset.forName("GBK"));
BufferedReader erbr = new BufferedReader(error);
line = null;
while ((line = erbr.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
3.执行本地脚本
public static void testBat() {
Process process;
//本地脚本地址,我的测试脚本内容就一句话ipconfig/all
String cmd = "D:\\testBat.bat";
try {
//执行命令
process = Runtime.getRuntime().exec(cmd);
//取得命令结果的输出流
InputStream inputStream = process.getInputStream();
//用一个读输出流类去读
InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("GBK"));
//用缓冲器读行
BufferedReader br = new BufferedReader(isr);
String line = null;
//知道读完为止
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
4.自动关机
public static void autoDown() throws IOException {
System.out.println("欢迎来到自动关机程序");
//用于创建接收用户输入的变量input
Scanner input = new Scanner(System.in);
System.out.println("请输入电脑关机倒计时时间(s)");
//获取用户输入信息
String text = input.nextLine();
//关机指令shutdown -s -t 时间
Runtime.getRuntime().exec("shutdown -s -t " + text);
System.out.println("你的电脑将在" + text + "s后关机");
System.out.println("如想取消关机请输入1");
//用于创建接收用户输入的变量input1
Scanner input1 = new Scanner(System.in);
//获取用户输入信息
String text1 = input1.nextLine();
//将String(字符串)型text1转换为int整型b
int b = Integer.parseInt(text1);
//判定b是否等于1
if (b == 1) {
//取消关机指令
Runtime.getRuntime().exec("shutdown -a");
System.out.println("关机已经取消");
}
}
注意:
- addShutdownHook,在linux环境下使用kill强制关闭服务的时候不会触发