Runtime详解,一文带你打通Java Runtime类及其相关知识。

这篇具有很好参考价值的文章主要介绍了Runtime详解,一文带你打通Java Runtime类及其相关知识。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文的宗旨是带你了解最全面的知识,让你能将学到的知识串联起来,构建一个完整的知识体系。

什么是Runtime

Runtime(运行时),每个Java程序在运行时都相当于启动了一个JVM实例,每个JVM实例都对应一个Runtime对象。Runtime对象是由JVM负责实例化的,因此我们无法通过传统的方式实例化一个Runtime对象,只能通过调用getRuntime()方法来获取当前运行时的Runtime对象的引用。

Runtime对象如何获取

java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试
查看Runtime类源码,我们可以发现Runtime只有一个空参的私有构造器,这意味着我们无法使用new来获取对象的实例,那么我们如何获取Runtime对象呢?这就引出了设计模式的概念。
Runtime类使用了设计模式中的饿汉模式来保证只能存在唯一一个对象实例

什么是设计模式?

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。
拿饿汉模式举例,饿汉模式属于设计模式中的单例设计模式,单例设计模式保证一个类只有一个实例。

回到代码中我们发现,由于Java将Runtime类的构造器设置为private,导致我们无法使用new来获取Runtime对象实例,那么我们就需要对外暴露一个新的方法来让外界可以获取Runtime对象。
这个时候就可以想到,使用static关键字修饰的方法可以通过类名.方法名直接调用,那么我们就可以通过设置一个public的静态方法来让外界调用。

解决了方法调用的问题,我们又遇到问题了,如何保证一个类仅仅只有一个实例呢?
如果我们让类保存自己的实例对象,并且在外界想要获取实例对象时将自己保存的实例对象交付出去,是不是就保证一个类只有一个实例了呢?

现在我们就明白了单例设计模式的基本思路,通过类自己来管理自己的实例,保证实例的唯一性。

值得注意的是,如果想在类中保存一个自己的实例,如果直接new,可能导致StackOverflowError错误,因为Test在实例化的过程中还会再次递归地实例化自己。正确的方法是在构造器中将实例对象赋值给成员变量,或者使用static关键字保证成员变量唯一
java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试

什么是饿汉模式

我们刚刚已经知道了单例设计模式的设计思路,那么我们继续了解两种单例设计模式,懒汉模式和饿汉模式。

  • 懒汉模式
    顾名思义,懒汉模式指这个类非常懒惰,它只有在真正需要这个类的实例时才会去实例化对象。如图所示,只有在调用getInstance()方法时才会实例化Singleton2并将其赋值给成员变量并返回
    java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试
  • 饿汉模式
    饿汉模式指这个类太饿了,它想要早点获得实例对象。可以看到,饿汉模式直接就将实例对象赋给了静态的成员变量。
    java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试
  • 测试是否是单例的
    java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试
    java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试

Runtime类有哪些方法,有什么用?

https://www.geeksforgeeks.org/java-lang-runtime-class-in-java/
以下内容来自机翻,大多数都很好理解,后面会详细介绍常用方法exec()。

方法 执行的操作
addShutdownHook(Thread hook) 注册新的虚拟机关闭挂钩线程。
availableProcessors() 返回 JVM(Java 虚拟机)可用的处理器数
exec(字符串命令) 在单独的进程中执行给定的命令
exec(字符串[] cmd) 在单独的进程中执行指定的命令和参数。
exec(String 命令, String[] envp, File dir) 在具有指定环境和工作目录的单独进程中执行指定的字符串命令。
exec(字符串命令,字符串[] envp) 在具有指定环境的单独进程中执行指定的字符串命令。
exec(String[] cmdarray, String[] envp, 文件目录) 在具有指定环境和工作目录的单独进程中执行指定的命令和参数。
exec(字符串[] cmdarray, 字符串[] envp) 在具有指定环境的单独进程中执行指定的命令和参数。
exit(int 状态) 通过启动当前正在运行的 Java 虚拟机的关闭序列来终止该虚拟机。
freeMemory() 函数 返回 JVM(Java 虚拟机)中的可用内存量
gc() 运行垃圾回收器。调用此方法表明 Java 虚拟机将工作扩展到回收未使用的对象,以便使它们当前占用的内存可供快速重用。
getRuntime() 函数 返回与当前 Java 应用程序关联的实例或运行时对象
halt(int 状态) 强制终止当前正在运行的 Java 虚拟机。此方法从不正常返回。使用此方法时应格外小心。
load(字符串文件名) 将指定的文件名加载为动态库。filename 参数必须是完整的路径名。
loadLibrary(字符串库名) 加载具有指定库名称的动态库。包含代码的文件是从本地系统从通常获取库文件的位置加载的。
maxMemory() 返回 Java 虚拟机将尝试使用的最大内存量。如果没有固有限制,则将返回值 Long.MAX_VALUE
removeShutdownHook(线程钩子) 取消注册以前注册的虚拟机关闭挂钩。
runFinalization() 运行任何待定终结的对象的终结方法。它表明 JVM(Java 虚拟机)将工作扩展到运行已发现已丢弃但其 finalize 方法尚未运行的对象的 finalize 方法。
totalMemory() 返回 JVM(Java 虚拟机)中的总内存量
traceInstructions(布尔值 a) 启用或禁用指令跟踪。如果布尔参数为 true,那么它将建议 JVM 在执行虚拟机中的每条指令时发出调试信息。
traceMethodCalls(布尔值 a) 启用或禁用对方法调用的跟踪。如果布尔参数为 true,则它将建议 Java 虚拟机在调用虚拟机时发出虚拟机中每个方法的调试信息。

addShutdownHookhook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。简单来说就是hook会监视某些特定的行为,并在这些行为出现时被触发,可以将它想象成一个陷阱。例如各种杀毒软件以及计算机病毒都会使用到这种技术。

native

观察源码我们发现,Runtime类中有许多方法用到了native关键字修饰,那么它有什么用呢?
一个Native修饰的方法是java调用非java代码的接口,比如C++。
他有具体的实现,但是实现的语言不是java,这主要是因为java是运行在JVM虚拟机中的,这虽然让java可以在许多平台上运行,但是如果要调用操作系统或者java环境外的方法时就显得比较无力,这时候就需要使用其他语言来帮助我们完成需要的操作。
简单来说,native方法的实现是借助了其他语言,脱离了java环境。

Runtime.getRuntime().exec()

作用:用于调用外部程序,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。功能就是和windows的“运行”(键盘按键 WINDOWS + R)一样。
该方法会抛出IOException异常

// 在单独的进程中执行指定的外部可执行程序的启动路径或字符串命令
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

参数说明:

  • cmdarray 包含所调用命令及其参数的数组。数组第一个元素是命令,其余是参数。
  • envp 字符串数组,其中每个元素的环境变量的设置格式为 name=value,如果子进程应该继承当前进程的环境,则该参数为null。
  • dir 子进程的工作目录,如果子进程应该继承当前进程的工作目录,则该参数为null。

比如我们可以通过Runtime.getRuntime().exec("notepad");来调用windows中的记事本。

假如我现在有一个python文件D:\CS\hello.py,作用是输出字符串hello World,我想通过Runtime.getRuntime().exec()调用并获取输出。

        try {
            // 构建命令
            String command = "python D:\\CS\\hello.py";

            // 执行命令并获取输出
            Process process = Runtime.getRuntime().exec(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

如果你想直接通过python命令来调用python程序,你需要将python添加到系统环境变量中。

ProcessBuilder

观察源码我们知道,Runtime.getRuntime().exec("")是调用ProcessBuilder类实现的,并返回一个Proces对象。这涉及到设计模式中的建造者模式,我将在下一篇文章中对这个类以及设计模式进行详细介绍。

我在使用过程中遇到的坑

重点!!!!!

  1. Runtime.getRuntime().exec()无法实时读取Python脚本的输出,而是要等到Python脚本运行完毕才会读取到输出。
    解决办法:使用 python -u参数,因为Python会默认将输出进行缓存,当使用"-u"选项时,Python将立即将输出发送到标准输出流,而不是等到缓冲区装满后再进行输出。这在某些情况下很有用,特别是当你希望实时查看程序输出时。
  2. 程序阻塞,所有进程都正常运行但是java获取不到输出。
    通过 Process实例.getInputStream() 和 Process实例.getErrorStream() 获取的输入流和错误信息流是缓冲池向当前Java程序提供的,而不是直接获取外部程序的标准输出流和标准错误流。
    而缓冲池的容量是一定的,因此若外部程序在运行过程中不断向缓冲池输出内容,当缓冲池填满,那么外部程序将暂停运行直到缓冲池有空位可接收外部程序的输出内容为止。
    java runtime机制,java,开发语言,设计模式,经验分享,单例模式,面试
    解决办法:新建线程持续读取输入输出流。
  3. 使用cmd命令但启动的新进程无法自动关闭
    使用cmd /k会导致进程不自动关闭,应该使用cmd /c

如果看到这里的话,能帮忙点个赞就太感谢了。如果觉得这篇文章不错,也可以点个关注,之后也会进行更多知识分享。您的支持是我继续创作的动力,十分感谢!

参考资料
https://blog.csdn.net/zjt1388/article/details/82656484
https://blog.csdn.net/qq_30336433/article/details/89634366
https://blog.csdn.net/footless_bird/article/details/116274515
https://blog.csdn.net/zhuwei1035838807/article/details/79464603
https://cloud.tencent.com/developer/article/1414936
https://www.geeksforgeeks.org/java-lang-runtime-class-in-java/文章来源地址https://www.toymoban.com/news/detail-860113.html

到了这里,关于Runtime详解,一文带你打通Java Runtime类及其相关知识。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 树,二叉树及其相关知识

    1.1树的概念 树是一种非线性的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点,称为根结点,根节点没有前驱结点 除根节点外,其余结点被分成M(M0)个

    2024年01月25日
    浏览(27)
  • 【Node.js实战】一文带你开发博客项目之登录(前置知识)

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,也会涉及到服务端 📃 个人状态: 在校大学生一枚,已拿多个前端 offer(秋招) 🚀 未来打算: 为中国的工业软件事业效力n年 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2Vue3项目实战 🥝

    2024年02月21日
    浏览(51)
  • 【硬件安全】一文带你了解单片机故障注入知识,绕过保护提取固件

    在物联网设备的物理安全评估期间,目标之一是利用调试接口或可访问的芯片来研究设备的工作原理。理想的情况是提取完整的文件系统,以找到一种方法来获取对设备的 root 访问权限。然后,可以更轻松地检查正在运行哪些服务,并在需要时对其进行调试,以最终控制目标

    2024年02月03日
    浏览(51)
  • Nginx配置详解,一文带你搞懂Nginx

    1 基本概念 1.1 Nginx简介 Nginx是一个高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现好。Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考验,有报告表明能支

    2024年01月16日
    浏览(50)
  • C生万物 | 十分钟带你学会位段相关知识

    结构体相关知识可以先看看这篇文章 —— 链接 位段的声明和结构是类似的,有两个不同: 位段的成员必须是 int 、 unsigned int 或 signed int 位段的成员名后边有一个冒号和一个数字 在下面,我分别写了一个结构体和一个位段, 注意看位段的写法和结构体有什么不同 然后我们

    2023年04月09日
    浏览(37)
  • 【Qt UI相关】Qt中如何控制 窗口的最大化、最小化和关闭按钮?一文带你掌握用法

    窗口的最大化、最小化和关闭按钮通常是由操作系统的窗口管理器控制的,而不是由应用程序控制的。这些按钮的行为(例如点击最大化按钮会将窗口的大小调整为屏幕的大小)是由窗口管理器实现的,应用程序通常不能改变这些行为。 在 Qt 中,你可以通过 QWidget::setWindow

    2024年02月11日
    浏览(42)
  • Java Runtime 类详解

    1. Runtime 介绍 Runtime 是 Java 提供的一个启动子进程来执行命令的方式,它提供了 6 个重载的 exec 方法,用于单独启动一个子进程来执行命令或调用程序。 public Process exec(String command) throws IOException public Process exec(String command, String[] envp) throws IOException public Process exec(String command

    2024年02月07日
    浏览(33)
  • 搜索引擎的基本原理、算法、用户画像及其他相关知识点

    作者:禅与计算机程序设计艺术 作为一个互联网公司,无疑需要做好搜索引擎的运营。每天都要搜索很多信息,如何做好搜索引擎的用户体验,提高用户的转化率是每家公司的核心竞争力。但实际上,做好搜索引擎运营也不是一件容易的事情,因为搜索引擎的特性、相关性算

    2024年02月04日
    浏览(64)
  • Java数据类型,一文带你彻底拿捏~

    ——Java中运算符是一种特殊的符号,用来进行数据的运算、赋值和比较等 思维导图 1.什么是算术运算符         ——算术运算符是用于数据类型值之间,使用2个或以上的数据进行运算 2.算术运算符概括 算术运算符 解释 示例 +,- 正号,负号 +10,-10 +,- 加,减 10 + 10,1

    2024年02月13日
    浏览(37)
  • MySQL(七):一文带你学透 mysql运算符 (超详解)

    本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远! 算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行

    2024年02月08日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包