Java控制台同时记录readLine而不会发生冲突

时间:2017-06-17 15:02:53

标签: java logging console

我目前正在处理以下问题: 我尝试为java应用程序创建一个控制台输入 适用于多个线程。所以在跑的时候 有时它会发生一个新的日志 出现在我用promt写入readLine的时候...... 当发生这种情况时,它看起来如下: Image of the Console 所以它确实堆叠了像图像中的消息..所以这是问题:

如何保留我写的文字和文字,并在上面记录文字,如下例所示? Gif of the input

(抱歉低质量,但你可以猜到我的意思)

正如您所看到的,我的输入位于底部,仍可编辑且线条不叠加

感谢您的帮助,在尝试Log4j,System.console,BufferedReaders和Scanner之后,我感到非常困惑

2 个答案:

答案 0 :(得分:1)

解决。这太复杂了...... 但这是为了未来:

class ConsoleThread implements Runnable {

private ConsoleReader reader;
private OutputStream output;

public ConsoleThread(OutputStream output, ConsoleReader reader) {
    this.output = output;
    this.reader = reader;
}

@Override
public void run() {

    try {

        String message;

        while (true) {

            message = LoggingQueue.getNextLogEvent();

            if(message == null) continue;

            reader.print(Ansi.ansi().eraseLine(Ansi.Erase.ALL).toString() + ConsoleReader.RESET_LINE);
            reader.flush();
            output.write((message + System.lineSeparator()).getBytes());
            output.flush();

            try {
                reader.drawLine();
            } catch (Throwable ex) {
                reader.getCursorBuffer().clear();
            }

            reader.flush();

        }

    } catch (IOException e) {
        Controller.handleException(Thread.currentThread(), e);
    }

}

使用jLine2和jAnsi的ConsoleReader。输出流只是System.out。

你只需要第二个线程来读取你已经完成了:)

答案 1 :(得分:0)

您需要处理竞争stdin / stdout的线程。 从理论上讲,这意味着某种互斥体,但是,既然你正在使用外部库,那似乎太麻烦......

从您的图片中,您似乎正在运行一种接收命令的服务器应用程序。 如果是这种情况,我建议重新架构使用两个单独的进程:一个用于服务器部分,另一个用于命令提示符。 然后这两个进程通过套接字进行通信。 这允许您使命令提示符成为单线程,或者至少表现得像单线程应用程序,因为它只对用户命令做出反应。

这就是很多应用程序,比如Docker,Kubernetes或MySQL。 对于Docker和Kubernetes,它们在该套接字上公开完整的REST API,以便您可以利用它。