【原创】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所衍生的,那些被执行的命令被称为子进程.子进程 ...
随机推荐
- CF 514C(hash)
传送门:Watto and Mechanism 题意:输入a个字符串和b个待检测字符串.问待检测字符串是否可以由某个已知字符串改变且只改变一个字母得到. 分析:字符串hash,枚举待测字符串每一位进行 ...
- Fragment总结
一.总体工程图: 二.main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android& ...
- NYOJ 914 Yougth的最大化
Yougth的最大化 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 Yougth如今有n个物品的重量和价值各自是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价 ...
- activity_main.xml: java.lang.NullPointerException
1.错误描写叙述 eclipse.buildId=4.4.0.I20140606-1215 java.version=1.7.0_67 java.vendor=Oracle Corporation B ...
- java 状态模式 解说演示样例代码
package org.rui.pattern; import junit.framework.*; /** * 为了使同一个方法调用能够产生不同的行为,State 模式在代理(surrogate)的 ...
- 最终结算“Git Windowsclient保存username与password”问题
Git - How to use netrc file on windows - Stack Overflow 这就是正确答案,我们已经验证过了,以下具体描写叙述一下解决方法: 1. 在Windows ...
- OCP读书笔记(15) - 管理SQL性能调优
SQL Tuning Advisor(STA): 使用oracle提供的程序包进行sql优化 SQL> conn scott/tiger SQL), name )); SQL> inser ...
- PreparedStatement与Statement
转载自:http://www.importnew.com/5006.html PreparedStatement是用来运行SQL查询语句的API之中的一个,Java提供了 Statement.Prep ...
- POJ 2365 Rope(水题)
[题意简述]:给出我们钉子个数与半径,让我们求出缠绕在钉子上的绳子有多长. [分析]:从题目中我们能够看出,绳子长度的和等于每两个钉子的距离的和加上接触在钉子上的绳子的长度,不难发现这部分长度事实上就 ...
- Android自己定义组件系列【2】——Scroller类
在上一篇中介绍了View类的scrollTo和scrollBy两个方法,对这两个方法不太了解的朋友能够先看<自己定义View及ViewGroup> scrollTo和scrollBy尽管实 ...