3

Runtime.exec()を使用して、Javaで単純な外部プロセスエグゼキュータを実装しました。プロセスの出力ストリームとエラーストリームからのプロセス出力を消費する「streamgobbler」クラスを実装しました。私のコードは、Process.waitFor()を使用して外部プロセスが完了するのを待ってから、プロセスのリターンコードを出力します。

私が経験している問題は、「ストリームゴブラー」が印刷を完了する前にプロセスが終了することです。そのため、Java出力(System.out)では、返された終了コードがプロセス出力/エラー行の中央に表示されます。

私の質問は、whileループで各StreamGobblerのアライブステータスをポーリングする代わりに、wait()/ notify()を使用してSystem.outの出力を同期することは可能ですか?

コードは次のとおりです。

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

public class RuntimeExecExample
{
    private enum StreamType
    {
        OUTPUT,
        ERROR
    }

    public class MyStreamGobbler extends Thread
    {
        private InputStream is;
        StreamType type;

        public MyStreamGobbler(InputStream is, StreamType type)
        {
            this.is = is;
            this.type = type;
        }

        public void run()
        {
            try
            {
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String line=null;
                while ( (line = br.readLine()) != null)
                {
                    System.out.println(type.toString() + ">" + line);
                }
            } 
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
    }

    public void executeCommand(String args[])
    {
        try
        {
            Runtime rt = Runtime.getRuntime();

            String commandLine = "";
            for(String cmdItem : args)
            {
                commandLine += " " + cmdItem;
            }
            System.out.println("Exec-ing " + commandLine);

            Process proc = rt.exec(args);
            // any error message?
            MyStreamGobbler errorGobbler = new MyStreamGobbler(proc.getErrorStream(), StreamType.ERROR);
            // any output?
            MyStreamGobbler outputGobbler = new MyStreamGobbler(proc.getInputStream(), StreamType.OUTPUT);
            // kick them off
            errorGobbler.start();
            outputGobbler.start();
            // any error???
            int exitVal = proc.waitFor();

            /*
             * Wait for both to finish before printing exit value
             * IS THERE A WAY TO DO THIS WITH wait()/notify() ??
             */
            while(errorGobbler.isAlive())
                ;
            while(outputGobbler.isAlive())
                ;

            System.out.println("ExitValue: " + exitVal);
        }
        catch (Throwable t)
        {
            t.printStackTrace();
        }

    }

    public static void main(String args[])
    {

        if(args.length < 1)
        {
            System.out.println("USAGE: java RuntimeExecExample <cmd> [<arg1> <arg2> ..]");
            System.exit(1);
        }
        else
        {
            RuntimeExecExample runtimeExecExample = new RuntimeExecExample();
            runtimeExecExample.executeCommand(args);
        }
    }

}
4

2 に答える 2

2

メイン スレッドで、サブプロセスを終了するために waitFor() を実行するだけでなく、errorGobbler.join() と outputGobbler.join() も実行すると、while(xGobbler.isAlive()) は必要なくなります。

于 2012-12-01T11:12:34.250 に答える