频繁更新控制台时回车符 '\r' 不可靠



>我正在控制台中显示进度,并使用"\r"字符清除每次更新之间的行,根据此答案。

public class MainTest {
    public static int delay = 10;
    public static void main(String[] args) {
        for (int i = 0; i <= 100; i++) {
            System.out.print("r");
            System.out.print("process:" + i + "%");
            Thread.sleep(delay);
        }
    }
}

延迟 240 毫秒或更长时间,它似乎工作正常。但是,一旦我低于此值,"\r"字符就不可靠了。它看起来很紧张,并不总是明确界限,所以最后你会看到

process:97%process:98%process:99%process:100%

此 gif 显示了更新速度之间的差异。我不希望我的程序运行得更慢,只是为了让控制台输出看起来不错。我该如何解决这个问题?

一种选择是将代码拆分为两个线程,并行运行。工作线程执行所有工作逻辑,并更新"进度"变量。您的 UI 线程会时不时地读取进度,并将其显示在控制台中。

import java.util.concurrent.atomic.AtomicInteger;
public class HelloWorld
{
    public static void main(String[] args) throws InterruptedException
    {
        final AtomicInteger progress = new AtomicInteger(0);
        Thread worker = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i <= 100; i++) {
                    try {
                        // Do some work here
                        Thread.sleep(1);
                        progress.set(i);
                    } catch (InterruptedException e) {
                        progress.set(100);
                    }
                }
            }
        });
        worker.start();
        while (progress.get() < 100) {
            // Now you can choose how often to update the console, without
            // slowing down your worker.
            Thread.sleep(240);
            System.out.print("r");
            System.out.print("Progress: " + progress.get() + "%");
        }
        worker.join();
    }
}

UI 代码在应用程序逻辑的单独线程上运行是很常见的,主要是这样当某些事情需要很长时间时,它不会阻止用户交互 - 他们仍然可以单击关闭、在选项卡之间切换等。

最新更新