Java执行Linux命令死锁阻塞挂起

在尝试使用Java的Runtime.exec执行Linux脚本时,遇到代码在waitFor方法处阻塞的问题。分析发现可能由输入流缓冲区满导致死锁。解决方案是通过多线程及时消费输入流数据,避免子进程和Java线程相互等待导致的死锁状态。
摘要由CSDN通过智能技术生成

1、前言:
最近在做一个需求需要调用linux下的某个脚本来对ai的模型进行训练,很简单的需求,我像往常一样写下如下的代码片段:
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
But当我运行代码时,发现代码执行到waitFor后阻塞住了,我以为这也许是训练模型需要时间,毕竟是同步阻塞的方法,那我就等一会吧!
一分钟……两分钟……10分钟……
我渐渐的意识到,这TM不对劲啊!
于是我通过以下命令查询了下linux执行情况。
ps aux |grep xxx.sh
输出的结果显示该脚本当前还在运行,而脚本的日志并没有从inputstream进行输出。我渐渐的慌了!

2 问题分析
2.1 观看JDK文档

根据查看JDK的文档,我看到Process.waitFor可能导致死锁?!仔细观看JDK的文档说明,发现文档上已经对死锁的情况进行了分析。
如果InputStream使用的buffer缓冲区有限的话,可能会导致阻塞和死锁 。
2.2 死锁原因

经过查阅资料,发现

  1. 当我们使用Runtime.exec执行命令时,JAVA的线程会创建一个子进程,用于执行命令,而且子进程和JAVA线程会分别独立运行。
  2. JAVA线程需要等待命令的执行完成,对命令的日志和返回值进行处理,所以我们在JAVA线程中调用Process.waitFor挂起来等待子进程完成。
  3. 子进程执行时,不断的打印日志信息,我们通过Process.g
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值