首页 > 其他分享 >RunTime.getRunTime().addShutdownHook用法

RunTime.getRunTime().addShutdownHook用法

时间:2023-09-14 12:04:11浏览次数:42  
标签:Runtime exec Process getRunTime cmd addShutdownHook new RunTime getRuntime


Runtime.getRuntime().addShutdownHook(shutdownHook);
这个方法的含义说明:
这个方法的意思就是在jvm中增加一个关闭的钩子,当jvm关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,当系统执行完这些钩子后,jvm才会关闭。所以这些钩子可以在jvm关闭的时候进行内存清理、对象销毁等操作。
[b]调用方:[/b]

Runtime runtime = Runtime.getRuntime();
EngineShutdownHook engineShutdownHook = new EngineShutdownHook();
runtime.addShutdownHook(engineShutdownHook);



[b]实现:[/b]


public class EngineShutdownHook extends Thread {
    private static Logger logger = Logger.getLogger(EngineShutdownHook.class.getName());

    public void run() {
        JediLogger.debug(logger, "EngineShutdownHook - run] Entering method.");
    	SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss dd-MM-yyyy");

		Timestamp timestampStop = new Timestamp(new java.util.Date().getTime());
		System.out.println("[INFO] " + simpleDateFormat.format(timestampStop) + " - Stopping INFO Engine...");
        Engine.stop();
        Timestamp timestampStopped = new Timestamp(new java.util.Date().getTime());
        System.out.println("[INFO] " + simpleDateFormat.format(timestampStopped) + " - INFO Engine stopped.");

        Timestamp timestampDestroy = new Timestamp(new java.util.Date().getTime());
        System.out.println("[INFO] " + simpleDateFormat.format(timestampDestroy) + " - Destroying INFO Engine...");
        Engine.destroy();

        Timestamp timestampDestroyed = new Timestamp(new java.util.Date().getTime());
        System.out.println("[INFO] " + simpleDateFormat.format(timestampDestroyed) + " - INFO Engine destroyed.");

        Timestamp timestampComplete = new Timestamp(new java.util.Date().getTime());
        System.out.println("[INFO] " + simpleDateFormat.format(timestampComplete) + " - Shutdown complete");

        Timestamp timestampHalt = new Timestamp(new java.util.Date().getTime());
        System.out.println("[INFO] " + simpleDateFormat.format(timestampHalt) + " - Halting JVM");
        JediLogger.debug(logger, "com.prft.jedi.engine.EngineShutdownHook - run] Leaving method.");
    }
}




测试类:


public class RunTimeTest {
	/**
	  * @param args
	  */
	 public static void main(String[] args) {
	  Thread thread1 = new Thread() {
	   public void run() {
	    System.out.println("thread1...");
	   }
	  };

	  Thread thread2 = new Thread() {
	   public void run() {
	    System.out.println("thread2...");
	   }
	  };

	  Thread shutdownThread = new Thread() {
	   public void run() {
	    System.out.println("shutdownThread...");
	   }
	  };

	  Runtime.getRuntime().addShutdownHook(shutdownThread);

	  thread1.start();
	  thread2.start();
	 }
}



打印结果:


thread2...


thread1...


shutdownThread...



或者:


thread2...


thread1...


shutdownThread...



结论:


无论是先打印thread1还是thread2,shutdownThread 线程都是最后执行的(因为这个线程是在jvm执行关闭前才会执行)。



exec(String[] cmdarray, String[] envp, File dir)



Executes the specified command and arguments in a separate process with the specified environment and working directory.



那个dir就是调用的程序的工作目录,这句其实还是很有用的。



Windows下调用程序


Process proc =Runtime.getRuntime().exec("exefile");




Linux下调用程序就要改成下面的格式


Process proc =Runtime.getRuntime().exec("./exefile");




Windows下调用系统命令


String [] cmd={"cmd","/C","copy exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);




Linux下调用系统命令就要改成下面的格式


String [] cmd={"/bin/sh","-c","ln -s exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);




Windows下调用系统命令并弹出命令行窗口


String [] cmd={"cmd","/C","start copy exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);




Linux下调用系统命令并弹出终端窗口就要改成下面的格式


String [] cmd={"/bin/sh","-c","xterm -e ln -s exe1 exe2"};
Process proc =Runtime.getRuntime().exec(cmd);




还有要设置调用程序的工作目录就要


Process proc =Runtime.getRuntime().exec("exeflie",null, new File("workpath"));



当然最好的执行系统命令的方法就是写个bat文件或是shell脚本。然后调用,那样修改和实现就简点多了。



用Java编写应用时,有时需要在程序中调用另一个现成的可执行程序或系统命令,这时可以通过组合使用Java提供的Runtime类和Process类的方法实现。



下面是一种比较典型的程序模式:


Process process = Runtime.getRuntime().exec("p.exe");
process.waitfor( );





在上面的程序中,第一行的“p.exe”是要执行的程序名,Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象的 exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。第二条语句的目的等待子进程完成再往下执行。 但在windows平台上,如果处理不当,有时并不能得到预期的结果。下面是笔者在实际编程中总结的几种需要注意的情况:



1、执行DOS的内部命令 如果要执行一条DOS内部命令,有两种方法。一种方法是把命令解释器包含在exec()的参数中。



例如,执行dir命令,在 NT上,可写成exec ("cmd.exe /c dir"),在windows 95/98下,可写成“command.exe /c dir”,其中参数“/c”表示命令执行后关闭Dos立即关闭窗口。另一种方法是,把内部命令放在一个批命令my_dir.bat文件中,在Java程序中写成exec("my_dir.bat")。如果仅仅写成exec("dir"),Java虚拟机则会报运行时错误。前一种方法要保证程序的可移植性,需要在程序中读取运行的操作系统平台,以调用不同的命令解释器。后一种方法则不需要做更多的处理。


2、打开一个不可执行的文件 打开一个不可执行的文件,但该文件存在关联的应用程序,则可以有两种方式。 以打开一个word文档a.doc文件为例,Java中可以有以下两种写法:


exec("start a.doc");
exec(" c:\\Program Files\\Microsoft Office\\office winword.exe a.doc");



显然,前一种方法更为简捷方便。



3、执行一个有标准输出的DOS可执行程序 在windows 平台上,运行被调用程序的DOS窗口在程序执行完毕后往往并不会自动关闭,从而导致Java应用程序阻塞在waitfor( )。导致该现象的一个可能的原因是,该可执行程序的标准输出比较多,而运行窗口的标准输出缓冲区不够大。解决的办法是,利用Java提供的Process 类提供的方法让Java虚拟机截获被调用程序的DOS运行窗口的标准输出,在waitfor()命令之前读出窗口的标准输出缓冲区中的内容。一段典型的程序如下:


String str;
Process process = Runtime.getRuntime().exec("cmd /c dir windows");
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(process.getInputStream());
while ( (str=bufferedReader.readLine()) != null) System.out.println(str);  
process.waitfor();

标签:Runtime,exec,Process,getRunTime,cmd,addShutdownHook,new,RunTime,getRuntime
From: https://blog.51cto.com/u_16261339/7468617

相关文章

  • grpc报错io.grpc.StatusRuntimeException: UNIMPLEMENTED: Service is unimplemented.
    如果被调用方的服务,proto文件上方定义了package,调用方不可以更改此路径!!!syntax="proto3";packagenucdl_FaceMatch;optionjava_multiple_files=true;optionjava_outer_classname="DLFaceProto";optionjava_package="com.nuctech.uranus.face.grpc"; ......
  • RuntimeException
    1.Java类库的每个包中都定义了异常类,所有这些类都是Throwable类的子类。Throwable类派生了两个子类,分别是Exception类和Error类。2.Error类及其子类用来描述Java运行系统中的内部错误以及资源耗尽的错误,这类错误比较严重。3.Exception类称为非致命性类,可以通过捕捉处理使程序继......
  • Kubernetes 初始化报错[ERROR CRI]: container runtime is not running:
    在linux上安装Kubernetes,初始化时报错:[root@k8s-master~]#kubeadminit\>--apiserver-advertise-address=10.10.10.180\>--image-repositoryregistry.aliyuncs.com/google_containers\>--kubernetes-versionv1.28.1\>--service-cidr=10.10.10.0/24......
  • 微服务启动失败,报错信息:java.lang.RuntimeException: dynamic-datasource Please chec
    【问题描述】Causedby:org.springframework.beans.factory.BeanCreationException:Errorcreatingbeanwithname'dataSource'definedinclasspathresource[com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceAutoConfiguration.cl......
  • 深入研究java.lang.Runtime类
    在线API:http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html转自:http://lavasoft.blog.51cto.com/62575/15565一、概述     Runtime类封装了运行时的环境。每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。     ......
  • 【开源】java版本BertTokenizer以及使用onnxruntime推理
    python训练的模型,转换为onnx模型后,用python代码可以方便进行推理,但是java代码如何实现呢?首先ONNX推理,可以使用onnxruntime<dependency><groupId>com.microsoft.onnxruntime</groupId><artifactId>onnxruntime</artifactId><version>1.15.1</version>......
  • XXX has been compiled by a more recent version of the Java Runtime (class file v
    maven版本未指定导致编译失败问题Executiondefaultofgoalorg.springframework.boot:spring-boot-maven-plugin:3.1.3:repackagefailed:Unabletoloadthemojo'repackage'intheplugin'org.springframework.boot:spring-boot-maven-plugin:3.1.3'dueto......
  • 给微软.Net runtime运行时提交的几个Issues
    前言因为目前从事的CLR+JIT,所以会遇到一些非常底层的问题,比如涉及到微软的公共运行时和即时编译器或者AOT编译器的编译异常等情况,这里分享下自己提的几个Issues。原文:微软.Netruntime运行时提交的几个IssuesIssues一.issuesone第一个System.Numerics.Vector库里面的成员......
  • Go 并发编程 - runtime 协程调度(三)
    GoRuntimeGoruntime可以形象的理解为Go程序运行时的环境,类似于JVM。不同于JVM的是,Go的runtime与业务程序直接打包在一块,是一个可执行文件,直接运行在操作系统上,效率很高。runtime包含了一些Go的一些非常核心的功能:协程调度、垃圾回收、内存分配等。本文将着重介绍......
  • Container Runtime Intro
    https://www.tutorialworks.com/difference-docker-containerd-runc-crio-oci/......