我正在尝试使用线程在 java 中的 CLI 上显示进度条,同时执行长时间操作(为一批大文件生成 md5sum)。
我已经编写了一些代码,并且它可以工作,但我想知道我是否正确使用了线程,因为我对此还很陌生。
我有两个类文件,ProgressThreadTest.java
和 CountToABillion.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/