【原创】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所衍生的,那些被执行的命令被称为子进程.子进程 ...
随机推荐
- EndNote是一款着名的参考文献管理软件
EndNote是一款着名的参考文献管理软件,我们可以通过该软件创建个人参考文献库,此外对公司DCC.法务和专 利部门十分的有用,甚至对我们写SOP 也有些帮忙,并且该软件可以在其中加入文本.图像.表格 ...
- skynet源代码学习 - 从全局队列中弹出/压入一个消息队列过程
学习云风的skynet源代码,简单记录下. void skynet_globalmq_push(struct message_queue * queue) { struct global_queue ...
- dvtm: 平铺式终端管理器 — LinuxTOY
dvtm: 平铺式终端管理器 — LinuxTOY LinuxTOY 是一个致力于提供 Linux 相关资讯的专题站点.如果您发现了好用好玩的 Linux 东东并愿意发扬自由.分享的精神,可以点击顶部 ...
- Spring3.0官网文档学习笔记(一)
Part 1 Spring框架概述 Spring是模块化的,在应用中仅仅须要引入你所须要用到的模块的jar包,其余的jar包不用引入. spring框架支持声明式的事务管理,通过RMI或web ser ...
- Python 分析Twitter用户喜爱的推文
CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-5 @author: guaguastd @name: an ...
- 智能手机的工业控制应用方案——SimpleWiFi在工业控制领域应用
智能手机的工业控制应用方案——SimpleWiFi在工业控制领域应用 先上图: 现在的智能控制都是基于微控制器,随着智能的手持终端的普及,基于智能终端的控制就会越来越普遍. WIFI便是其中的一 ...
- GMM高斯混合模型学习笔记(EM算法求解)
提出混合模型主要是为了能更好地近似一些较复杂的样本分布,通过不断添加component个数,能够随意地逼近不论什么连续的概率分布.所以我们觉得不论什么样本分布都能够用混合模型来建模.由于高斯函数具有一 ...
- Android 检測网络是否连接
权限: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <u ...
- hdu 4925 贪心 自己从小到大做数据找方法规律
http://acm.hdu.edu.cn/showproblem.php?pid=4925 自己逐个做数据找规律.提供下我的找的: 1 2 1 3 2 2 2 3 3 3 然后发现这种矩阵是最优的: ...
- Working with forms
翻译 Django文档 Version 1.5 https://docs.djangoproject.com/en/1.5/topics/forms Working with forms 关于此文章: ...