`

Java中Process的waitFor()阻塞问题

    博客分类:
  • Java
阅读更多

在做视频转换时,调用外部的 exe 去进行一些视频转换的操作时,因为考虑到速度问题,当时是通过启动多个线程来共同完成某个操作的,因为是多线程操作,所以当时我控制的主线程等待所有子线程执行完后再继续向下去执行。但是始终出现发现没有控制住子线程未执行完主线程就向下继续执行的情况,开始因为是启动多线程时线程控制问题,后来发现是子线程中利用 Process 调用外部 exe 时出现了 waitFor() 方法阻塞问题(唉,折腾啊)。 Ok ,知道问题就好解决了。

首先来解释一下 waitFor() 方法的意义, waitFor() 表示当前 Process 所在的子线程处于等待状态,如有必要,一直要等到由该 Process 对象表示的进程已经终止,网上说如果我们在调用此方法时,如果不注意的话,很容易出现主线程阻塞, Process 也挂起的情况。这就是我遇到的问题,网上的解决办法是,在调用 waitFor() 的时候, Process 需要向主线程汇报运行状况,所以要注意清空缓存区,即 InputStream ErrorStream ,注意这里 InputStream ErrorStream 都需要清空。

 

package com.iflytek.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 
 * @author xdwang
 * 
 * @ceate 2012-7-20 下午22:52:25
 *  
 * @email xdwangiflytek@gmail.com
 * 
 * @description 清除process里的InputStream和ErrorStream 缓存
 * 
 */
public class ProcessClearStream extends Thread {
	private InputStream inputStream;
	private String type;

	ProcessClearStream(InputStream inputStream, String type) {
		this.inputStream = inputStream;
		this.type = type;
	}

	public void run() {
		try {
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream);
			BufferedReader br = new BufferedReader(inputStreamReader);
			// 打印信息
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println(type + ">" + line);
			}
			// 不打印信息
//			 while (br.readLine() != null);
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
}

 

 

此时,我们再看看 Process 调用 exe 的方法:

 

package com.iflytek.util;

/**
 * @author xdwang
 * 
 * @ceate 2012-7-20 下午22:22:44
 * 
 * @email xdwangiflytek@gmail.com
 * 
 * @description process工具类
 * 
 */
public class ProcessUtil {

	/**
	 * @descrption 执行外部exe公用方法
	 * @author xdwang
	 * @create 2012-7-20下午22:24:32
	 * @param cmdStr
	 *            命令字符串
	 */
	public static void execProcess(String cmdStr) {
		Process process = null;
		try {
			System.out.println(cmdStr);
			process = Runtime.getRuntime().exec(cmdStr);
			new ProcessClearStream(process.getInputStream(), "INFO").start();
			new ProcessClearStream(process.getErrorStream(), "ERROR").start();
			int status = process.waitFor();
			System.out.println("Process exitValue: " + status);
		} catch (Exception e) {
			System.out.println("执行" + cmdStr + "出现错误," + e.toString());
		} finally {
			if (process == null) {
				process.destroy();
			}
			process = null;
		}
	}

}

 

 

 

 

分享到:
评论

相关推荐

    JAVA Process 使用

    `Process`对象的`waitFor()`方法会阻塞直到进程结束,返回值是进程的退出码: ```java int exitCode = process.waitFor(); System.out.println("Process exited with code: " + exitCode); ``` ### 6. 销毁进程 ...

    java调用windows命令

    process.waitFor(); ``` 5. **删除文件** - 使用`Runtime.getRuntime().exec()`删除文件时,必须包含命令解释器,例如: ```java Process process = Runtime.getRuntime().exec("cmd /c del f:\\aaa.doc"); `...

    java执行可执行文件或批处理

    需要注意的是,如果命令的执行时间过长,`waitFor()`方法也会阻塞较长时间,因此在实际应用中要考虑到这一点。 ### 总结 通过Java的`Runtime`类,我们可以轻松地执行外部的可执行文件和批处理文件。这种方式不仅...

    Java中使用Runtime和Process类运行外部程序.docx

    为避免此问题,你需要在`waitfor()`之前读取并处理`Process`的标准输出,清空缓冲区。 在处理外部进程时,一定要注意异常处理,确保正确关闭输入、输出和错误流,避免资源泄漏。同时,考虑到跨平台兼容性,可能需要...

    java中调用本地exe文件

    在Java编程语言中,有时我们需要实现与操作系统交互的功能,例如执行一些特定的本地应用程序或脚本等。本文将详细介绍如何在Java中调用本地exe文件,并解析提供的代码示例。 ### 一、Java中调用本地exe文件的基本...

    Java代码中调用shell脚本和python脚本并获得输出结果(分为小数据量和大数据量).docx

    原因是`process.waitFor()`会在输入流缓冲区填满之前阻塞,导致进程无法继续输出数据。为了解决这个问题,我们可以使用一个额外的线程来不断地从输入流中读取数据,这样就可以确保数据能够及时被处理,而不会堵塞...

    JAVA调用DOS命令.pdf

    通过调用 Process 对象的 waitFor 方法,可以阻塞当前 JAVA 线程,直到命令执行完毕。 但是,需要注意的是,如果该命令是有标准输出或者是错误输出的话,必须在 waitFor 方法阻塞之前,通过读取 Process 对象的 ...

    JAVA中如何执行DOS指令_.docx

    当执行的DOS程序会产生大量标准输出时,可能导致DOS窗口不会自动关闭,从而阻塞Java程序的`waitfor()`方法。这是因为DOS窗口的标准输出缓冲区可能不足以存储所有输出。为了解决这个问题,可以使用Java的`Process`类...

    JAVA如何调用WINDOWS命令行.doc

    这可能导致Java应用程序在调用`waitFor()`方法时出现阻塞。 解决此问题的一种方法是在调用`waitFor()`之前先读取DOS窗口的标准输出缓冲区的内容。可以使用Java的`BufferedReader`来实现这一点: ```java String ls...

    JAVA如何调用DOS命令

    解决的办法是,利用 Java 提供的 Process 类提供的方法让 Java 虚拟机截获被调用程序的 DOS 运行窗口的标准输出,在 waitfor() 命令之前读出窗口的标准输出缓冲区中的内容。 删除文件 在删除文件时,需要注意 ...

    Java调用本地的远程桌面连接

    process.waitFor(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 在这个例子中,`/v:`参数指定目标计算机地址,`/u:`参数传递用户名,`/p:`参数传递密码。执行`exec()`...

    Java cmd命令行模拟工具

    `process.waitFor()`方法会阻塞直到命令执行完毕。 对于更复杂的命令,如需要参数、环境变量或者管道操作,可以使用`ProcessBuilder`类。例如,下面的代码创建了一个`ProcessBuilder`实例,设置了命令和参数,并将...

    编程语言java批处理.pdf

    在执行之后,可以使用`Process`对象的方法来管理这个子进程,比如`waitFor()`方法可以阻塞当前线程,直到子进程结束。 另外,文档中提到了使用批处理(Batch)文件进行操作。批处理文件通常包含一系列命令,可以一...

    JAVA如何调用DOS命令.doc

    - 当被调用的DOS程序有大量的标准输出时,其DOS窗口可能不会自动关闭,导致`waitfor()`方法阻塞。这是因为输出缓冲区可能已满。为解决这个问题,你可以通过`Process`对象的`getInputStream()`方法获取标准输出流,...

    通过JAVA执行命令行程序

    int exitCode = process.waitFor(); System.out.println("Process exited with code " + exitCode); ``` 在这个例子中,我们创建了一个ProcessBuilder实例,然后异步地启动进程。通过读取输出流,我们可以在不影响...

    java 调用doc命令

    `waitFor()`方法会阻塞直到命令执行完毕,返回值是命令的退出状态码,0通常表示成功。 5. **注意安全性和权限** 调用系统命令可能存在安全风险,如潜在的命令注入攻击。因此,确保只传递受信任的输入,并尽可能...

    java代码中调用linux/unix命令

    调用`Process.waitFor()`方法可以阻塞当前线程,直到命令执行完成。别忘了关闭输入输出流,防止内存泄漏。 5. **异常处理和错误检查** 通过`Process.exitValue()`检查命令执行是否成功。正常退出时,返回值为0;...

    JAVA-DOS-command.rar_DOS java_dos command_java dos_shelf

    - **等待命令完成**:调用`process.waitFor()`来阻塞当前线程,直到命令执行完成。 - **清理资源**:确保关闭所有打开的流,并且在不再需要进程时调用`process.destroy()`。 3. **示例代码**: 以下是一个简单的...

    Java调用相应cmd命令的实例

    int exitCode = process.waitFor(); // 等待命令执行完成并获取退出码 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader....

    Java调用Linux命令

    - `waitFor()`:阻塞当前线程,直到子进程完成。 - `destroy()`:销毁子进程,使其立即终止。 ### 示例代码 下面是一个简单的示例,演示如何使用`Runtime.exec()`来执行Linux命令“ls”: ```java public class ...

Global site tag (gtag.js) - Google Analytics