如何添加另一个控制台来与多线程程序进行交互

时间:2012-11-30 21:52:42

标签: java multithreading console pipe gnu-screen

我有一个单线程程序在做一些长时间运行的计算工作。主线程使用控制台进行输出。我正在考虑添加另一个线程来与用户交互,以查询诸如作业进度或进程内部状态之类的内容。

假设正确处理了同步,并且用户通过命令行控制台之类的东西与第二个线程进行交互(无需GUI)。实现此功能的好方法是什么?我想我可以让第二个线程在某个命名管道上等待命令,并让用户使用像GNU屏幕这样的东西连接到这个管道(我不确定它是否会起作用)。

是否有任何库(Java或非Java)或工具来实现它?我的程序在Linux上运行。

2 个答案:

答案 0 :(得分:1)

执行您想要的操作实际上需要两个命名管道:每个方向一个。在这方面使用套接字可能是更好的选择(尽管处理服务器端可能有点困难)。

至于客户端,我不认为GNU / Screen可以用来做这件事。如果使用命名管道,客户端应该只使用cat(实际上有两个cat进程:一个写入服务器,一个读取答案)。如果您实现基于套接字的通信,则可以使用netcatnc)作为客户端。

答案 1 :(得分:1)

您需要另一个线程来读取用户的输入。我就是这样做的......

package com.mycompany.readthread;

import java.io.*;

public class Launcher {
    public static void main(String[] args) {
        new Launcher().run();
    }

    public void run() {
        LongRunningJob job = new LongRunningJob();
        ReadInputLoop readInputLoop = new ReadInputLoop(job);
        Thread readInputLoopThread = new Thread(readInputLoop);
        readInputLoopThread.start();  // run read input loop in another thread
        job.run();  // run long running job in this thread
    }

    class LongRunningJob implements Runnable {
        private double percentageComplete;

        @Override
        public void run() {
            // long running job
            // update percentageComplete in a synchronized block
        }

        public synchronized double getPercentageComplete() {
            return percentageComplete;
        }
    }

    class ReadInputLoop implements Runnable {
        private LongRunningJob job;               

        public ReadInputLoop(LongRunningJob job) {
            this.job = job;            
        }

        @Override
        public void run() {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            try {
                while (true) {
                    String line = br.readLine();
                    if ("exit".equalsIgnoreCase(line)) {
                        break;
                    }
                    if ("progress".equals(line)) {
                        double percentageComplete = job.getPercentageComplete();
                        System.out.println(String.format("%.3g", percentageComplete)+ "%");
                    }
                }                
            }
            catch (IOException ex) {
                System.err.println("Unexpected exception");
            }
        }
    }
}