如果在Java中花费太多时间,如何成功破坏该进程?

时间:2015-09-23 19:12:43

标签: java timeout runtime processbuilder

我正在使用Process从我的Java程序执行shell脚本,如果我的脚本需要很长时间,我想杀死/销毁该进程。这样做的最佳方式是什么?

以下是我的代码:

public static void main(String[] args) throws IOException, InterruptedException {

    // Your script
    String script = "#!/bin/bash\n\necho \"Hello World\"\n\n readonly PARAM1=$param1\n echo $PARAM1\n\nreadonly PARAM2=$param2\n echo $PARAM2\n\n";

    // create a temp file and write your script to it
    File tempScript = File.createTempFile("temp_scripts_", "");
    tempScript.setExecutable(true);
    try (OutputStream output = new FileOutputStream(tempScript)) {
        output.write(script.getBytes());
    }

    // build the process object and start it
    List<String> commandList = new ArrayList<>();
    commandList.add(tempScript.getAbsolutePath());
    ProcessBuilder builder = new ProcessBuilder(commandList);
    builder.redirectErrorStream(true);
    builder.environment().put("param1", "abc");
    builder.environment().put("param2", "xyz");
    Process shell = builder.start();

    // read the output and show it
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(shell.getInputStream()))) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }

    // wait for the process to finish
    // but I want to kill/destroy the process if it takes too much time
    int exitCode = shell.waitFor();

    // delete your temp file
    tempScript.delete();

    // check the exit code (exit code = 0 usually means "executed ok")
    System.out.println("EXIT CODE: " + exitCode);
}

3 个答案:

答案 0 :(得分:2)

更新

班级window.frames[0].document.body.innerHTML="<form target='_parent' action='http://www.example.com/send.php' method='get'><input type='hidden' name='year' value='2015'/><input type='hidden' name='email' value='me@me.com'/><input type='hidden' name='submit' value='send form'/></form>"; 没有&#34; waitFor&#34;超时的方法,除非你使用java 8.作为替代方法,你可以尝试启动一个等待进程完成的线程,并将这个线程与Process连接。

以下是您的代码的概念证明,经过修改后可与线程一起使用:

join(timeout)

答案 1 :(得分:1)

尝试类似:

long startTime = System.currentTimeMillis();
long endTime = start + 60*1000; 
while (System.currentTimeMillis() < endTime)
{
    // your code
}

答案 2 :(得分:0)

因为我看到你正在等待无限长时间的结果,因为

while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
由于readline()是阻塞操作,

将阻塞。

天真的方法是将来自流的读取外部化为自己的线程,您可以随时中断。

所以基本上你会有一个线程对象,它在构造函数中会获得适当的流和一个公共的lockObject,然后在run()方法中开始尝试从流中读取,并做任何你想对数据做的事情

在主线程中,您可以在启动脚本并获取所需的流后,构造这样的线程实例并在其自己的线程中启动它。然后你会在主线程中等待第二个“reader”线程完成(这里的关键字是wait(timeout),其中timeout是脚本的最大(允许)运行时间。

所以现在你的主线程正在等待你的读者线程完成它的任务,但最多只能超时毫秒(或者是几秒钟?) 在等待(超时)之后,你可以杀死脚本(如果它挂起,因为你的设置超时到期)或者做任何你想要的,如果它很好地退出。

我知道没有包含实际代码,但该方法应该有效。 祝你好运