为Process.waitFor设置超时

Java中在使用Runtime.getRuntime().exec(command)调用系统命令后
一般会调用Process.waitFor()来等待命令执行结束 获取执行结果
今天一个悲剧的事实证明了
即使只是调用了很简单的脚本命令
在调用Process.waitFor()后同样可能发生无休止或者接近于无休止的阻塞
处理完故障之后痛定思痛
决定在代码中加入超时控制
但是Process.waitFor()本身并不支持超时时间设置
一个方法是改用非阻塞的Process.exitValue()方法
然后轮询检查进程状态 这种方式比较消耗CPU
以至于轮询间隔也不能设置得太小 总归不是很完美
另外就是多起一个线程
借助于其他的超时机制来控制
最后使用的代码如下

public class ProcessUtils {

    /**
     * 运行一个外部命令,返回状态.若超过指定的超时时间,抛出TimeoutException
     * @param command
     * @param timeout
     * @return
     * @throws IOException
     * @throws InterruptedException
     * @throws TimeoutException
     */
    public static int executeCommand(final String command, final long timeout) throws IOException, InterruptedException, TimeoutException {
        Process process = Runtime.getRuntime().exec(command);
        Worker worker = new Worker(process);
        worker.start();
        try {
            worker.join(timeout);
            if (worker.exit != null){
                return worker.exit;
            } else{
                throw new TimeoutException();
            }
        } catch (InterruptedException ex) {
            worker.interrupt();
            Thread.currentThread().interrupt();
            throw ex;
        } finally {
            process.destroy();
        }
    }

    private static class Worker extends Thread {
        private final Process process;
        private Integer exit;

        private Worker(Process process) {
            this.process = process;
        }

        public void run() {
            try {
                exit = process.waitFor();
            } catch (InterruptedException ignore) {
                return;
            }
        }
    }

}

为Process.waitFor设置超时

时间: 2024-10-20 10:19:47

为Process.waitFor设置超时的相关文章

socket为send和recv设置超时时间

linux和windows下用setsockopt设置SO_SNDTIMEO,SO_RCVTIMEO的参数的一点区别 UDP的socket在某些情况:如对方关闭时,本地可能sendto不出去数据,然后recvfrom就会被阻塞,这时就需要设置 这两个参数的值提高程序质量. linux: struct timeval timeout={3,0};//3s    int ret=setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeo

java测试网络连接是否成功并设置超时时间

/** * 获取RMI接口状态 * * @return "0":服务正常,"1": 连接报错,"2":连接超时 */ @Override public String getRMIJkzt() { final ExecutorService es = Executors.newFixedThreadPool(1); Callable<String> callable = new Callable<String>() {//使

设置超时时间(项目案例仅供参考)

#设置超时时间爬取网页速度相对要快些#encoding:utf8from lxml import etree#xpathimport re#正则import time#时间import requests#传值from selenium import webdriver#通用阅览器from selenium.webdriver.support.ui import WebDriverWait#引用超时模块import random#自定义模块url = '(网址)'driver = webdrive

C# UdpClient 设置超时时间

/********************************************************************** * C# UdpClient 设置超时时间 * 说明: * 网络通信中设置超时时间是常有的时,记录UDP获取.发送超时设置方法. * * 2016-12-8 深圳 南山平山村 曾剑锋 *********************************************************************/ 一.参考文档: 1. Can

设置超时时间

// 设置超时时间 [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"]; manager.requestSerializer.timeoutInterval = 10.f; [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"]; http://www.itjhwd.com/ios-xuexzlzl/

htmlagilitypack 设置超时

htmlagilitypack timeout 设置超时 http://blog.jongallant.com/2012/07/htmlagilitypack-set-timeout.html htmlWeb.PreRequest = request => { request.Timeout = 15000; return true; }; htmlWeb.PreRequest = request => { request.Timeout = 15000; return true; };

Axis2 客户端调用 设置超时时间

我用的是axis2-1.6.2版本.请看下面的客户端代码: import org.apache.axis2.client.Options; import com.ctis.ta.service.impl.OpenAccountForUnitServiceStub;import com.ctis.ta.service.impl.OpenAccountForUnitServiceStub.OpenAndCheck;import com.ctis.ta.service.impl.OpenAccount

Unix网络编程 高级IO套接字设置超时

我们知道,对于一个套接字的读写(read/write)操作默认是阻塞的,如果当前套接字还不可读/写,那么这个操作会一直阻塞下去,这样对于一个需要高性能的服务器来说,是不能接受的.所以,我们可以在进行读写操作的时候可以指定超时值,这样就读写操作就不至于一直阻塞下去. 在涉及套接字的I/O操作上设置超时的方法有三种: 1:调用alarm,它在指定的超时期满时产生SIGALRM信号.这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用. 2:在select中阻

如何给ExecutorService异步计算设置超时

ExecutorService接口使用submit方法会返回一个Future<V>对象,Future表示异步计算的结果.它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果.计算完成后只能使用get方法来获取结果,如有必要,计算完成前可以阻塞此方法.取消则由cancel方法来执行.还提供了其他方法,以确定任务是正常完成还是被取消了.一旦计算完成,就不能再取消计算.如果为了可取消性而使用Future但又不提供可用的结果,则可以声明Future<?>形式类型.并返回nul