【原创】java中的父进程子进程 —— 坑爹的java Runtime.getRuntime().exec
最近有一个需求,需要用一个java进程启动多个子进程来完成并发任务。由于必须给用户完成任务的反馈,所以需要父进程记录子进程的生命周期。
exec方法返回一个Process对象,在当前进程内调用该对象的waitFor方法,然后父进程就会在该方法阻塞,那么只有在该Process结束的情况下,才会从waitFor中返回。
我写了两个类来测试:
一个是Father类:
public class Father {
private static int count = 0;
private static int total = 3;
private static String target = "./hell.jar";
private static List<Process> child = new ArrayList<Process> ();
public static void main (String[] args) {
Runtime run = Runtime.getRuntime();
System.out.println("wait..");
for (int i = 0; i < total; i ++) {
try {
Process num = run.exec("java -jar " + target);
child.add(num);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (Process item : child) {
try {
item.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("All work finished!");
}
}
hell.jar由子类son导出,具体代码如下:
public class Son {
public static void main (String[] args) {
for (int i = 0; i < 10000; i ++) {
System.out.println(i);
}
System.exit(0);
}
}
可是,可是!
明明应该很快结束,结果整整卡了15分有余。。
后来上网查了,才发现这是个坑
文档中如此写道:
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.
这意思简单概括为:缓冲区如果满了,爷就挂起来
换言之,子进程把写往stdout的缓冲区占满了,所以子进程挂起了,于是父进程就要消逝在永久的等待中了。
了解了原因,解决办法就简单了:消耗掉输出。
我的办法是重定向。
但是对exec重定向似乎也有坑。。Goolge了一个解决办法,具体代码如下:
public class Father {
private static int count = 0;
private static int total = 3;
private static String target = "./hell.jar";
private static List<Process> child = new ArrayList<Process> ();
public static void main (String[] args) {
Runtime run = Runtime.getRuntime();
System.out.println("wait..");
for (int i = 0; i < total; i ++) {
try {
Process num = run.exec("cmd /c java -jar " + target + " 1>>1.txt 2>&1"); // 把stdout和stderr的输出重定向到1.txt中
child.add(num);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (Process item : child) {
try {
item.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("All work finished!");
}
}
然后就成功了。
感想:
bat真丑,windows上java的坑真多
【原创】java中的父进程子进程 —— 坑爹的java Runtime.getRuntime().exec的更多相关文章
- JAVA命令运行cmd命令得到的结果乱码Runtime.getRuntime().exec("");
Process process = Runtime.getRuntime().exec("cmd /c dir c:"); BufferedReader bufferedReade ...
- Java中如何创建进程(转)
在Java中,可以通过两种方式来创建进程,总共涉及到5个主要的类. 第一种方式是通过Runtime.exec()方法来创建一个进程,第二种方法是通过ProcessBuilder的start方法来创建进 ...
- 使用Runtime.getRuntime().exec()在java中调用python脚本
举例有一个Python脚本叫test.py,现在想要在Java里调用这个脚本.假定这个test.py里面使用了拓展的包,使得pythoninterpreter之类内嵌的编译器无法使用,那么只能采用ja ...
- Runtime.getRuntime().exec中命令含有括号问题
在写批量运行bat工具的时候.想起了之前写的定时小工具里面的运行方法. 使用Runtime.getRuntime().exec方法. Runtime.getRuntime().exec("c ...
- [转]java调用外部程序Runtime.getRuntime().exec
Runtime.getRuntime().exec()方法主要用于执行外部的程序或命令. Runtime.getRuntime().exec共有六个重载方法: public Process exec( ...
- JAVA调用可执行程序或系统命令Runtime.getRuntime().exec
用Java编写应用时,有时需要在程序中调用另一个现成的可执行程序或系统命令,这时可以通过组合使用Java提供的Runtime类和Process类的方法实现.下面是一种比较典型的程序模式: Proces ...
- Java Runtime.getRuntime().exec() 执行带空格命令
可执行文件路径如果包含空格,则在java中不能被获取到. 此时Debug一下,会发现 project=null. project.waitFor 的返回值为1.但是去源路径单击bat文件是可以正常运行 ...
- Runtime.getRuntime().exec()实现Java调用python程序
使用Runtime.getRuntime().exec()来实现Java调用python,调用代码如下所示: import java.io.BufferedReader; import java.io ...
- linuxbash 父进程 子进程
linux登陆linux,就获得一个bash,之后你的bash就是一个独立的进程,被称为pid的就是,之后你在bash下面执行的任何命令都是由这个bash所衍生的,那些被执行的命令被称为子进程.子进程 ...
随机推荐
- [Android学习笔记]Android Library Project的使用
RT http://developer.android.com/tools/projects/index.html
- IE6,IE7,IE8下报JS错误:expected identifier, string or number的原因及解决的方法
今天在调试一个页面的时候遇到一个问题,在IE9下执行得非常好的脚本,在IE8里打开的时候弹出错误:expected identifier, string or number,依照经验,应该是定义对象的 ...
- The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
出现 The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the j ...
- TestApe - Unit testing for embedded software
TestApe - Unit testing for embedded software About this site Welcome - This site is TestApe.com. Mos ...
- Application to find the maximum temperature in the weather dataset
import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop. ...
- c++map按value排序--将map的pair对保存到vector中,然后写比较仿函数+sort完成排序过程。
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行 ...
- python列表和QVariant
pyqt中.要给QAbstractTableModel的setData函数传递一个list參数: [20,'00:00:19'] 涉及到QVariant和list的转换. 能够使用QVariant类中 ...
- LeetCode——Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given ...
- eval、json.parse()的介绍和使用注意点
原文:eval.json.parse()的介绍和使用注意点 eval和json.parse的使用 eval:来源于官网 定义和用法 eval() 函数可计算某个字符串,并执行其中的的 JavaScri ...
- Java多线程使用场景
使用多线程就一定效率高吗? 有时候使用多线程并不是为了提高效率,而是使得CPU能够同时处理多个事件. 使用场景1 为什么了不阻塞主线程,启动其他线程来做耗时的事情. 比如app开发中耗时的操作都不在U ...