关于JAVA输入输出流造成的Runtime线程阻塞问题【新人笔记】

2023-10-27

萌新最近搬砖遇到一个问题,上面让我做一个dump文件的自动解析系统,至于解析的工具,准备用的是google的breakpad,项目部署环境是linux+jdk1.8。其他的无关紧要也就不谈了。

一开始写了一个demo放到测试机上面跑,最初代码如下(只保留转换相关的代码,所以不可以运行):

import java.io.InputStreamReader;

public class DumpAnalyseUtil {

    public static boolean analyseDumpFile(String stackPath, String dumpPath, String symPath, String logPath){
        boolean result = false;
        Process process = null;

        File stackFile = new File(stackPath);
        File dumpFile = new File(dumpPath);
        File symbolFile = new File(symPath);
        File logFile = new File(logPath);

        try{
            if (stackFile.exists() && dumpFile.exists() && symbolFile.exists()){
                String command = stackPath + " " + dumpPath + " " + symPath + " > " + logPath;
                System.out.println(command);
                Runtime.getRuntime().exec(command).waitFor();
                result = true;
            }
        }catch (Exception e){
            System.out.println("Dump File Analysis Error: " + e.getMessage());
            if (process != null){
                try{
                    process.getErrorStream().close();
                    process.getInputStream().close();
                    process.getOutputStream().close();
                }catch (IOException ie){
                    ie.printStackTrace();
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        String stackPath = "/data/breakpad/src/processor/minidump_stackwalk";
        String dumpPath = "/data/dump/lalala.dmp";
        String symPath = "/data/symbols/";
        String logPath = "/data/symbols/123456.log";
        boolean result = analyseDumpFile(stackPath, dumpPath, symPath, logPath);
        System.out.println(result);
    }
}

在测试环境中运行这个demo的时候,程序跑到waitFor()方法那里就卡住不动了。。。

后来发现是自己的java基础还是有些薄弱,java在执行runtime命令时,输入流和错误流都会不断地进入JVM的缓冲区(一般来说不会有输出流,但是如果我们的命令和java程序有信息交互的话,比如需要我们通过程序输入什么参数的时候,这时候也会产生一些输出流进入缓冲区,但是这些输出流应该很快就被读取了,所以出现阻塞一般都是输入流和错误流引起的)。如果我们不去将缓冲区的这些信息流读出来的话,他们就会一直待在缓冲区,并最终将其填满,造成runtime的阻塞。

知道了问题的所在,就好解决了。既然这些数据流不读取就会淤积的话,读出来就好了,于是有了改进第一版(只放了改进的那部分代码):

Process exec = Runtime.getRuntime().exec(command);

BufferedReader insertReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(exec.getErrorStream()));

exec.waitFor();

还有一种方式,就是如果这个错误输出流里面的信息对你来说没有什么价值的话,可以利用ProcessBuilder的redirectErrorStream方法,来把错误流和输入流整合到一起,一并读出来:

ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectErrorStream(true);
Process p = processBuilder.start();
InputStream is = p.getInputStream();
BufferedReader bs = new BufferedReader(new InputStreamReader(is));

另外,如果你的输入流信息非常多,比如拷贝文件的话,则可以单独起一个线程来读取输入流中的信息:

(这一块是参考了 望星辰大海 的博客中的代码 点击打开链接

就不具体放出来了,有兴趣可以点击链接过去看一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于JAVA输入输出流造成的Runtime线程阻塞问题【新人笔记】 的相关文章

随机推荐

  • YOLOV8-网络结构

    代码下载链接 https download csdn net download weixin 40723264 88011324 一 整体网络 本文结合YOLOv5网络进行讲解 通过与YOLOv5网络进行比较 进一步理解YOLOv8 尽快上
  • Go语言学习笔记——jwt跨域鉴权

    文章目录 Golang jwt跨域鉴权 jwt介绍 JWT 到底是什么 JWT 和 OAuth 选择签名方法 签名方法和密钥类型 安装jwt 简单使用 生成JWT 解析jwt 测试 生成token并解析token jwt在项目中的使用 第一
  • Java学习 时间类 Period类与Duration类 / LocalDate类与Instant类 用法详解

    Java学习 时间类 Period类与Duration类 LocalDate类与Instant类 用法详解 前言 java 8 中引入的两个与日期相关的新类 Period 和 Duration 两个类看表示时间量或两个日期之间的差 两者之间
  • 交易日均千万订单的存储架构设计与实践

    一 订单系统概述 1 1 业务范围 服务业务线 快递 快运 中小件 大件 冷链 国际 B2B合同物流 CLPS 京喜 三入三出 采购入 退货入 调拨入 销售出 退供出 调拨出 等 1 2 订单中心价值 1 解耦 提升系统稳定性 原系统 交易
  • ERP现状及未来发展趋势分析?

    经过多年发展 ERP作为最重要的管理软件为国内外各类型企业所普遍接受 在我国 ERP行业已经进入成熟期 随着云计算 物联网等技术的推进 国内外竞争环境日益加剧 后ERP时代 表现出以下发展趋势 第一 商业智能化建设加强 经过多年运用 ERP
  • Linux下psql的使用(一):安装、建库、建表、数据载入、删除

    Linux下psql的使用 一 安装 建库 建表 数据载入 删除 一 Install PostgreSQL Database 安装Postgresql sudo apt get install postgresql 登录PostgreSQL
  • Java-类中代码块的使用

    Java 类中代码块的使用 1 概念 代码块 初始化块 代码块用来初始化类和对象 代码块如果有修饰的话 只能使用static 静态代码块和非静态代码块的区别 静态 内部可以有输出语句 随着类的加载而运行 初始化类的属性 一个类中定义了多个静
  • Java编程思想之《一切都是对象》理解

    前言 Java编程思想 中提到 Java是基于C 的 但相比之下 Java是一种 纯粹 的面向对象的程序设计语言 Java中不再使用指针来操作内存中的元素 而是采用对象的 引用 这个引用是作者提出的一种为了简化概念上的理解和C 语言的引用有
  • android 检查fragment是否已绑定到activity

    if isAdded 确定fragment是否绑定到Activity mPhotoRecyclerView adapter PhotoAdpter mItems
  • Linux初步入门学习 1

    一基础入门 command options partment1 partment2 命令 选项 参数1 参数2 cd 返回上一级目录 cd Desktop 进入桌面目录 cd usr bin 进入一般目录 ls 列出所有文件 lp line
  • 蓝桥杯大写变小写C语言,小写数字转化为大写数字(小米OJ题与蓝桥杯题)

    import java util public class Main public static void main String args Scanner scan new Scanner System in String str Str
  • Git本地仓库文件的创建、修改和删除

    目录 基本信息设置 1 设置用户名 2 设置用户名邮箱 Git仓库操作介绍 1 创建一个新的文件夹 2 在文件内初始化git仓库 创建git仓库 3 向仓库中添加文件 1 创建一个文件 2 将文件添加到暂存区 3 将暂存区添加到仓库 4 修
  • JavaScript贪心算法

    贪心算法 贪心算法有 霍夫曼编码 prim和kruskal最小生成树算法 Dijkstra最短路径算法 什么是贪心算法 1 针对一组数据 问题有限制值和期望值 希望从中选出几个数据 在满足限制值的情况下 期望值最大 2 每次选择当前情况下
  • UVA1601 The Morning after Halloween

    UVA1601 The Morning after Halloween 题目链接 做这道题的时候看到一个写的很好的代码 在这里保存下来 以便以后学习 题目分析 这道题和普通的bfs有所不同 解题方法也有些差别 主要是这里有三个移动的 小鬼
  • ant打包提示找不到文件解决办法

    运行ant打包时如果出现提示找不到tools目录下某些jar或者bat文件的错误 是因为新版android sdk目录结构产生了变化 原本在sdk tools目录下的文件被转移到sdk build tools 各个版本号文件夹中 需要复制里
  • matlab将数据输出到excel中,matlab数据输出为excel表格-如何把matlab中的数据导到excel表格中...

    如何将matlab工作空间的数据导出到excel 1 很简单的用xlswrite函数就可以了 首先打开matlab 输入你的代码 2 找到你要存放文件的位置复制绝对路径 致谢文件名的话就会存放在当前目录中 如图以f盘根目录为例 3 然后写x
  • 微信小程序集成和使用mqtt(同时支持uniapp和原生)

    前言 在集成mqtt到小程序的开发过程中 确实走了不少弯路 下了许许多多的示例 一步步踩坑到现在终于完美解决了小程序引入mqtt的方法 该方法原生和uniapp均适用 1 小程序网页配置 先登录微信公众平台 找到开发 开发管理 开发设置页面
  • 记录--MMDeploy安装、python API测试及C++推理

    目录 1 前言 2 MMDeploy安装 2 1 下载代码仓库 2 2 安装构建和编译工具链 2 3 创建Conda虚拟环境 2 4 安装MMDeploy SDK依赖 2 5 安装推理引擎 2 6 设置PATH 2 7 编译安装依赖库 3
  • EleAtt-RNN: Adding Attentiveness to Neurons in Recurrent Neural Networks

    EleAtt RNN Adding Attentiveness to Neurons in Recurrent Neural Networks EleAtt RNN 在循环神经网络的神经元当中加入注意力 1 创新点 现在研究者研究RNN 把
  • 关于JAVA输入输出流造成的Runtime线程阻塞问题【新人笔记】

    萌新最近搬砖遇到一个问题 上面让我做一个dump文件的自动解析系统 至于解析的工具 准备用的是google的breakpad 项目部署环境是linux jdk1 8 其他的无关紧要也就不谈了 一开始写了一个demo放到测试机上面跑 最初代码