StreamGobbler - 线程接受输入吗? Java的

时间:2013-12-13 12:13:18

标签: java multithreading loops output

使用自编StreamGobbler运行php脚本, 我正在尝试在脚本运行时输入命令...

StreamGobbler.java

private class StreamGobbler extends Thread {
    InputStream is;
    OutputStream os;
    String line;
    PMRunnerPro main;

    public StreamGobbler(InputStream is, OutputStream os, PMRunnerPro main) {
        this.is = is;
        this.os = os;
        this.main = main;
    }

    @Override
    public void run() {
        try {
            BufferedReader reader = new BufferedReader (new InputStreamReader(is));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));


            line = reader.readLine();
            while (line != null && ! line.trim().equals("--EOF--")) {
                if (main.sSendNeeded) {
                    System.out.println("Sent");
                    writer.write(main.sCommand + "\n");

                    main.sSendNeeded = false;
                    main.sCommand = "";
                }
                main.outputBox.setText(main.outputBox.getText() + (line + "\n"));
                line = reader.readLine();
            }
            writer.flush();

        } catch(IOException ex) {
            main.sRunning = false;
        }

        System.out.println("Over");
        main.sRunning = false;
    }
}

仅当脚本有输出时,才会将命令发送到脚本。

我希望Thread能够不断检查是否有任何命令发送到脚本,然后如果有任何命令则执行此操作。

1 个答案:

答案 0 :(得分:0)

如果我理解你的意图......

由于您使用阻塞I / O,因此您需要两个线程:

  • 第一个线程将像您现在一样读取脚本输出。输出可用后,将显示在textarea;
  • 第二个线程将读取队列中的输入并将其转发给脚本。

这是代码草案(请注意,您可能希望在输入和输出工作程序之间添加同步,因此输入worker将无法向脚本发送新命令,直到上一个命令从脚本生成输出,但这取决于您):

class InputWorker implements Runnable {
    @Override
    public void run() {
        try {
            BufferedReader reader = new BufferedReader (new InputStreamReader(is));
            String line = reader.readLine();
            while (line != null && ! line.trim().equals("--EOF--")) {
                // show script output
            }
        } catch(IOException ex) {
            //
        }
    }
}

class OutputWorker implements Runnable {
    final BlockingQueue<String> commandQueue = new ArrayBlockingQueue<String>();

    public void sendCommand(String command) {
        commandQueue.add(command);
    }

    @Override
    public void run() {
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));

            while (true) {
                String command = commandQueue.take();
                if ("EXIT".equals(command)) { return; }
                writer.write(command);
                writer.flush();
            }

        } catch(IOException ex) {
            //
        } catch (InterruptedException e) {
            // 
        }
    }
}