在 java 如何为多个线程创建通用进度指示器
in java how to create a common progress indicator for multiple threads
如果我有 5 个线程在工作,当它们开始工作时,它们会发送一个 progress-start 命令,让我们说一个开始旋转的进度轮。当一个线程停止工作时,它会向轮子发送一个进度停止。
可以很容易地看出,这将不起作用,因为仍在工作的最后一个线程已将其 progress-start 已被停止的最后一个线程删除。
我在考虑某种堆栈fifo/lifo实现来记住哪个线程在做什么,然后正确地告诉进度轮它应该处于什么状态。
但感觉它可能会坏掉,记住线程状态..
也许进度轮可以 运行 计时器每 3 秒定期检查线程是否存活
有 ide 吗?
您可以做的一件事是拥有一个 CountDownLatch。 CountDownLatch 的好处是,您可以将 ProgressWheel 作为一个新线程,而主线程将一直等到计数器达到 0。每个 WorkerThread 都会在其构造函数中传递 CountDownLatch,并在 运行方法完成。
如果工作线程不是一次全部启动,则必须使用计数器,在一个线程完成时递减计数,在一个线程启动时递增计数,并在进度轮中轮询其值。
这是一个示例代码
public static void main(String[] args) {
ProgressWheel wheel = new ProgressWheel();
CountDownLatch latch = new CountDownLatch(3);
wheel.start();
new WorkerThread(latch).start();
new WorkerThread(latch).start();
new WorkerThread(latch).start();
try {
latch.await(); //wait until counter reaches 0
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wheel.stop();
}
private static class WorkerThread extends Thread{
private CountDownLatch counter;
public WorkerThread(CountDownLatch counter) {
this.counter = counter;
}
@Override
public void run() {
//Do some heavy work
counter.countDown(); //This thread is finished
}
}
我建议在使用线程时避免堆栈或任何其他依赖于顺序的操作,线程完成的顺序几乎没有保证。
相反,尝试使用 Future 界面来跟踪线程完成。例如,当每个线程向进度轮发出它已完成的信号时,进度轮可以调用 Future.isDone()
之前调用过的任何其他任务以确定它是否应该停止。
使用Future
接口的另一个好处是您可以捕获任务抛出的任何异常或错误(例如InterruptedException
或ExecutionException
),然后将适当的消息发送到你的进度轮。
如果我有 5 个线程在工作,当它们开始工作时,它们会发送一个 progress-start 命令,让我们说一个开始旋转的进度轮。当一个线程停止工作时,它会向轮子发送一个进度停止。
可以很容易地看出,这将不起作用,因为仍在工作的最后一个线程已将其 progress-start 已被停止的最后一个线程删除。
我在考虑某种堆栈fifo/lifo实现来记住哪个线程在做什么,然后正确地告诉进度轮它应该处于什么状态。
但感觉它可能会坏掉,记住线程状态..
也许进度轮可以 运行 计时器每 3 秒定期检查线程是否存活 有 ide 吗?
您可以做的一件事是拥有一个 CountDownLatch。 CountDownLatch 的好处是,您可以将 ProgressWheel 作为一个新线程,而主线程将一直等到计数器达到 0。每个 WorkerThread 都会在其构造函数中传递 CountDownLatch,并在 运行方法完成。
如果工作线程不是一次全部启动,则必须使用计数器,在一个线程完成时递减计数,在一个线程启动时递增计数,并在进度轮中轮询其值。
这是一个示例代码
public static void main(String[] args) {
ProgressWheel wheel = new ProgressWheel();
CountDownLatch latch = new CountDownLatch(3);
wheel.start();
new WorkerThread(latch).start();
new WorkerThread(latch).start();
new WorkerThread(latch).start();
try {
latch.await(); //wait until counter reaches 0
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
wheel.stop();
}
private static class WorkerThread extends Thread{
private CountDownLatch counter;
public WorkerThread(CountDownLatch counter) {
this.counter = counter;
}
@Override
public void run() {
//Do some heavy work
counter.countDown(); //This thread is finished
}
}
我建议在使用线程时避免堆栈或任何其他依赖于顺序的操作,线程完成的顺序几乎没有保证。
相反,尝试使用 Future 界面来跟踪线程完成。例如,当每个线程向进度轮发出它已完成的信号时,进度轮可以调用 Future.isDone()
之前调用过的任何其他任务以确定它是否应该停止。
使用Future
接口的另一个好处是您可以捕获任务抛出的任何异常或错误(例如InterruptedException
或ExecutionException
),然后将适当的消息发送到你的进度轮。