【原创】java中的父进程子进程 —— 坑爹的java Runtime.getRuntime().exec

最近有一个需求,须要用一个java进程启动多个子进程来完成并发任务。因为必须给用户完成任务的反馈,因此须要父进程记录子进程的生命周期。java

exec方法返回一个Process对象,在当前进程内调用该对象的waitFor方法,而后父进程就会在该方法阻塞,那么只有在该Process结束的状况下,才会从waitFor中返回。windows

 

我写了两个类来测试:并发

一个是Father类:ide

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);

	}
}

  

但是,但是!orm

明明应该很快结束,结果整整卡了15分有余。。对象

 

后来上网查了,才发现这是个坑blog

文档中如此写道:生命周期

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

相关文章
相关标签/搜索