【问题标题】:StreamGobbler - Thread to accept input into it? JavaStreamGobbler - 接受输入的线程?爪哇
【发布时间】:2013-12-13 12:13:17
【问题描述】:

使用自编的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;
    }
}

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

我希望线程不断检查是否有任何命令要发送到脚本,如果有的话就这样做。

【问题讨论】:

    标签: java multithreading loops output


    【解决方案1】:

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

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

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

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

    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) {
                // 
            }
        }
    }
    

    【讨论】:

    • 你能解释一下我如何将上面的代码与我当前的代码一起使用吗?我的应用程序包含一个用于编写命令的文本框,一旦按下按钮,命令将写入sCommand,同时使sSendNeeded 为真。然后线程会注意到sSendNeeded 是真的,然后会写sCommand
    • @junyi00 不是将值写入sCommand,而是调用inputFromElsewhere
    • @junyi00 实际上,现在我更好地理解了您的需求,线程之间不需要通信:输出线程应该像您的 OP 中一样,只需不检查输入。输入线程应使用如上所示的队列从运算符获取数据并将其传递给脚本。
    • @junyi00 我想我已经用更相关的代码更新了答案。
    • 对不起,我很少使用 Runnable 类型,这是我第一次创建这样的应用程序。你能解释一下我如何将上面的代码实现到上面的线程中吗?
    猜你喜欢
    • 2016-02-16
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 2012-07-23
    相关资源
    最近更新 更多