java waitfor导致进程挂起一例

简介:
线上使用java做hive的任务调度,通过java  Runtime 类的exec方法来执行hive的job。最近发现有job卡死的情况。具体表现是调度的脚本挂起,而且还可能导致hive的lock不能正常释放。

使用jstack打印java的thread信息:
发现如下的lock,最终定位到waitFor函数。
1
2
3
4
5
6
7
8
"main"  prio= 10  tid= 0x000000005b24c800  nid= 0x280e  in Object.wait() [ 0x00002b3dee8e7000 ]
    java.lang.Thread.State: WAITING (on object monitor)
         at java.lang.Object.wait(Native Method)
         - waiting on < 0x00000000eb6f88b8 > (a java.lang.UNIXProcess)
         at java.lang.Object.wait(Object.java: 485 )
         at java.lang.UNIXProcess.waitFor(UNIXProcess.java: 165 )
         - locked < 0x00000000eb6f88b8 > (a java.lang.UNIXProcess)
         at calltest.main(calltest.java: 8 )
在java的api中发现关于的Runtime类的描述,每个jvm都有一个Runtime类的实例,Runtime类会起一个单独的进程来运行相关的命令
Every Java application has a single instance of class Runtimethat allows the application to interface with
the environment in which the application is running.
Executes the specified string command in a separate process with the specified environment and working directory.
同时,发现如下的解释:
即由exec生成的进程没有自己的console,会和父进程有IO操作联系,在输出数据比较大的时候,可能会导致缓冲区写满,从而导致进程死锁,而当前进程由于设置了waitFor会一直在等待子进程结束,从而当前子进程也进入阻塞状态。
The created subprocess does not have its own terminal or console. All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (getOutputStream(), getInputStream(), getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
waitFor方法:
causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
解决方法:
可以在调用waitFor方法之前,为子进程创建两个线程,来读取标准输出和标准错误输出即可。



本文转自菜菜光 51CTO博客,原文链接:http://blog.51cto.com/caiguangguang/1352708,如需转载请自行联系原作者
相关文章
|
3月前
|
监控 算法 Java
【JavaEE】什么是多线程?进程和线程的区别是什么?如何使用Java实现多线程?
【JavaEE】什么是多线程?进程和线程的区别是什么?如何使用Java实现多线程?
|
4月前
|
安全 Java API
深入了解Java进程和线程
深入了解Java进程和线程
53 1
|
3月前
|
消息中间件 设计模式 Java
Java Review - Java进程内部的消息中间件_Event Bus设计模式
Java Review - Java进程内部的消息中间件_Event Bus设计模式
59 0
|
1天前
|
Java API 调度
[Java并发基础]多进程编程
[Java并发基础]多进程编程
|
17天前
|
监控 Java Linux
linux下监控java进程 实现自动重启服务
linux下监控java进程 实现自动重启服务
|
3月前
|
Java
Java中的进程与线程
Java中的进程与线程
32 0
|
3月前
|
安全 Java API
深入了解Java进程和线程
深入了解Java进程和线程
40 1
|
3月前
|
Java 程序员 调度
JAVA 并发编程 进程、线程、协程
程序是静态的,程序运行后变为一个进程,一个进程内部可以有多个线程同时执行。进程是所有线程的集合,每一个线程是进程中的一条执行路径
|
4月前
|
Java Linux 微服务
linux中一键杀死springclud等各个java进程
linux中一键杀死springclud等各个java进程
|
4月前
|
Java API 调度
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)
55 0
Java多线程基础(线程与进程的区别,线程的创建方式及常用api,线程的状态)