1

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

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

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

4

2 回答 2

1

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

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

于 2012-11-30T23:02:51.877 回答
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");
            }
        }
    }
}
于 2012-11-30T23:21:50.770 回答