java - 在命令行上更新线程进度

标签 java multithreading command-line progress-bar command-line-interface

我正在尝试使用线程在 java 中的 CLI 上显示进度条,同时执行长时间操作(为一批大文件生成 md5sum)。

我已经编写了一些代码,并且它可以工作,但我想知道我是否正确使用了线程,因为我对此还很陌生。

我有两个类文件,ProgressThreadTest.javaCountToABillion.java

CountToABillion.java:

public class CountToABillion implements Runnable {

    double count = 0;

    public void echoCount() {
        System.out.println(count);
    }

    @Override
    public void run() {     
        for (double x=0;x<1000000000;x++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            count = x;
            echoCount();
        }       
    }   
}

ProgressThreadTest.java:

public class ProgressThreadTest {

    public static void main(String[] args) throws InterruptedException {

        Thread doCount=new Thread(new CountToABillion());
        doCount.start();
    }   
}

它按预期工作并在命令行上向上计数。

有人对这是否是一种处理线程的好方法有任何评论吗?

另外,因为我是在计数循环中更新进度,所以它将每 10 毫秒更新一次。如何更改代码以每秒仅输出一次计数?

最佳答案

使用javax.swing.Timer可能是更简单的解决方案:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class CountToABillion implements Runnable {

    double count = 0;
    Timer progressTimer;

    public void echoCount() {
        System.out.println(count);
    }

    @Override
    public void run() {
        progressTimer = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                echoCount();
            }
        });
        progressTimer.setRepeats(true);
        progressTimer.start();

        for (double x=0;x<1000000000;x++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            count = x;
        }
        progressTimer.stop();
    }
}

使用java.util.concurrent.ScheduledThreadPoolExecutor是更好且更具可扩展性的解决方案:

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CountToABillion implements Runnable {

    double count = 0;
    ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);

    public void echoCount() {
        System.out.println(count);
    }

    @Override
    public void run() {
        Runnable task = new Runnable() {
            public void run() {
                echoCount();
            }
        };
        exec.scheduleAtFixedRate(task, 1, 1, TimeUnit.SECONDS);

        for (double x=0;x<1000000000;x++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            count = x;
        }
        exec.shutdownNow();
    }
}

关于java - 在命令行上更新线程进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17488501/

相关文章:

java - 在 jsf/xhtml 中使用 foreach

java - 如何从 .conf 运行 jar?

java - IE11 上的 Selenium 自动化(企业模式)

c++ - Visual C++ 2008 Boost 问题

iphone - 如何从命令行将 iPhone 应用程序部署到模拟器?

java - 从命令行 Linux 运行 Java 程序

java - 当 HTML 文件包含 mdash 时,如何使用 Xerces 避免 SAXParseException?

android - 从线程传递消息以更新 UI

java - 我对 Java 多线程的长期困惑。需要帮忙

无法识别 Javac。 (已经设置路径)