Java进程与父子进程的标准输出流关联导致线程卡死的故障

故障现象

    Java调度系统创建PHP数据脚本后,并且获取其标准输出流,然后循环读取其标准输出流内容。此时PHP数据脚本执行时间过长,Java调度系统Process.destory()杀掉进程后,ps也无法找到对应PHP数据脚本,但Java的线程却无法退出,依然卡死在读取标准输出流。曾经怀疑是kill无法清理干净进程,于是变为强制执行kill -9杀掉超时的PHP数据脚本,但情况依旧,Java线程依然卡死。

    Java创建PHP数据脚本的代码大致如下:

childProcess = Runtime.getRuntime().exec(cmd);
    stream = childProcess.getInputStream();
    while ((size = stream.read(bytes)) != -1) {
    //处理输出流数据
    }

    //子进程退出
    //...


故障分析

    首先利用jstack找出对应线程堆栈,堆栈如下所示:

"TaskThread-CRON556" prio=10 tid=0x00007f4e38005800 nid=0x3563 runnable [0x00007f4f4167c000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(FileInputStream.java:272)
        ......

    可以发现线程卡死在java.io.FileInputStream.readBytes(Native Method)这个native方法中,查找对应的native代码,发现最终是linux的系统调用read方法。于是通过jstack上该线程对应的nid,0x3563转换10进制为13667 ,使用命令

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值