简体   繁体   English

在Java中如何为多个线程创建公共进度指示器

[英]in java how to create a common progress indicator for multiple threads

If I have 5 threads that do work and when they start work they send a progress-start command to lets say a progress wheel that start spinning. 如果我有5个正在工作的线程,并且当他们开始工作时,它们会发送一个progress-start命令给可以说开始旋转的进度轮。 When a thread stop work it send a progress-stop to the wheel. 线程停止工作时,它将进度停止发送到转轮。

On can easy see that this will not work since the last thread that are still working has gotten his progress-start removed by the last thread who stopped. 可以很容易地看到,由于最后一个仍在工作的线程的进度开始已被最后一个停止的线程删除,因此这将不起作用。

I was thinking about some kind of stack fifo/lifo implementation to remember what thread is doing what, and then correctly tell the progress wheel what state it should be in. 我在考虑某种堆栈fifo / lifo实现,以记住什么线程在做什么,然后正确地告诉进度轮应该处于什么状态。

But that feels like it can get broken, remembering thread states.. 但这感觉像是坏了,记住了线程状态。

Maybe the progress wheel could run a timer periodically every 3 sec check if threads are alive Any ide? 也许进度轮可以每3秒定期运行一个计时器,以检查线程是否处于活动状态。

One thing you could do is having a CountDownLatch. 您可以做的一件事就是拥有CountDownLatch。 The good thing about a CountDownLatch is, that you can make the ProgressWheel as a new thread, and the main thread will just wait until the counter reaches 0. Every WorkerThread would just get passed the CountDownLatch in its constructor and count it down when the run method is finished. CountDownLatch的好处是,您可以将ProgressWheel设置为新线程,并且主线程将一直等待直到计数器达到0。每个WorkerThread都将在其构造函数中传递CountDownLatch并在运行时对其进行递减计数方法完成。

If the worker threads are not started all at once, you would have to use a counter, count it down when a thread finishes, count it up when one start and poll its value in the progress wheel. 如果工作线程不是一次全部启动,则必须使用一个计数器,在线程结束时将其递减,在一次启动时将其递增并在进度轮中轮询其值。

Here is a sample code 这是示例代码

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
    }
}

I would recommend avoiding stacks or any other order dependent operation when working with threads, there is little to no guarantee on the order of thread completion. 我建议在使用线程时避免使用堆栈或任何其他依赖顺序的操作,几乎无法保证线程完成的顺序。

Instead, try using the Future interface to keep track of thread completion. 而是尝试使用Future接口来跟踪线程完成情况。 For example when each thread signals to the progress wheel that it has finished the progress wheel can call Future.isDone() on any other tasks that have been previously called to determine if it should stop. 例如,当每个线程向进度轮发出信号说它已经完成时,进度轮可以在先前已调用的任何其他任务上调用Future.isDone()以确定它是否应该停止。

Another advantage of using the Future interface is that you can catch any exceptions or errors (eg InterruptedException or ExecutionException ) thrown by the task and then send an appropraite message to your progress wheel. 使用Future接口的另一个优点是,您可以捕获任务抛出的任何异常或错误(例如InterruptedExceptionExecutionException ),然后将适当的消息发送到进度盘。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM