在使用Process执行shell命令时,如果使用APIexitValue()来判断shell是正常结束(即exit 0)还是异常结束,则可能引发异常:java.lang.IllegalThreadStateException: process hasn’t exited

因为exitValue方法没有阻塞,如果执行shell命令的进程还没有结束,则会引发异常,源码实现如下:

public synchronized int exitValue() {
         if (!hasExited) {
             throw new IllegalThreadStateException("process hasn't exited");
         }
         return exitcode;
     }

解决方法

  1. 在循序读取shell命令的输入时一定要关闭流

        public static void main(String[] args) throws IOException, InterruptedException {
        Process pr = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "sh test.sh"});
        BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        String result;
        while ((result = br.readLine()) != null) {
            System.out.println(result);
        }
        br.close();
        System.out.println(pr.exitValue());
    }
    

    while结束后,必须执行close函数,关闭输出流,不然进程还是未结束状态,直接执行exitValue()还是会抛出异常。

    1. 使用waitFor方法
      waitFor方法会一直阻塞直到shell命令执行进程完成,并返回执行结果。如果进程无法执行完成,waitFor方法将一直阻塞下去,其源码实现如下:
        public synchronized int waitFor() throws InterruptedException {
           while (!hasExited) {
               wait();
           }
          return exitcode;
       }
      

更多推荐

java.lang.IllegalThreadStateException: process hasn‘t exited异常解决方案