java 父进程_【原创】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 child = new ArrayList ();

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 child = new ArrayList ();

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的坑真多

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值