繁体   English   中英

Java等待池中的所有线程

[英]java wait all threads in pool

当按下暂停按钮并重新运行播放按钮时,是否有办法等待执行程序池中的所有线程? 我尝试了CountDownLatch,但我不知道我必须在执行程序声明之后还是在run()方法中放置它? 我没有关于线程的太多信息。请有人可以告诉我我该怎么做。

 public static CountDownLatch waiter;
public static ExecutorService pool;

public Action() throws InterruptedException{
    pool=Executors.newFixedThreadPool(2);
    waiter=new CountDownLatch(2); // to wait
    robot1=new Robot(0,560,"rbt1"); // starts random free position
    robot2=new Robot(0,560,"rbt2");
    if(Frame.pause==false){
       pool.submit(robot1);
       pool.submit(robot2);}
    if(Frame.pause==true){
        waiter.await();
    }


}

您可以等待所有线程完成:

pool.awaitTermination(60, TimeUnit.SECONDS); // hopefully 60 seconds are enough

请参阅: http : //docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination%28long,%20java.util.concurrent.TimeUnit%29

您的机器人工作人员需要一种共享的线程安全方式来检查工作人员是否应该暂停或玩耍。 在工作程序的run()方法中,如果线程已暂停,请等待此锁对象的通知。 在循环或执行工作时,定期检查锁定状态,并在需要时暂停工作。

pauseIfNeeded() {
    synchronized(workerLock) {
        if (workerLock.isPaused()) {
            workerLock.wait();
        }
    }
}

您的暂停和播放按钮应该在workerLock上获得同步锁,并设置暂停的属性,然后在workerLock上调用notify()。 这将使工作人员根据需要暂停或继续。 不管暂停/播放状态如何,执行器始终处于“运行中”状态。

编辑您可以将上述代码重构为自己的类,如下所示:

public class WorkerPauseManager {

    private boolean paused;

    public synchronized void pauseIfNeeded() throws InterruptedException {
        if (paused) wait();
    }

    public synchronized void pause() {
        this.paused = true;
    }

    public synchronized void start() {
        this.paused = false;
        notifyAll();
    }
}

创建一个WorkerPauseManager实例。 将此实例传递给您的所有Robot工人,并保留参考作为挥杆暂停/播放动作的参考。 您的工作线程应调用pauseIfNeeded。

这是使用WorkerPauseManager的SCCE:

public class WorkerPauseManagerTest {
    public static void main(String[] args) {
        final WorkerPauseManager pauseManager = new WorkerPauseManager();
        new Worker("Worker 1", pauseManager).start();
        new Worker("Worker 2", pauseManager).start();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JToggleButton playPauseButton = new JToggleButton(new AbstractAction("Pause") {
                    public void actionPerformed(final ActionEvent e) {
                        JToggleButton source = (JToggleButton) e.getSource();
                        if (source.isSelected()) {
                            pauseManager.start();
                            source.setText("Pause");
                        } else {
                            pauseManager.pause();
                            source.setText("Play");
                        }
                    }
                });
                JOptionPane.showMessageDialog(null, playPauseButton, "WorkerPauseManager Demo", JOptionPane.PLAIN_MESSAGE);
                System.exit(0);
            }
        });

    }

    private static class Worker extends Thread {
        final String name;
        final WorkerPauseManager pauseManager;

        public Worker(final String name, final WorkerPauseManager pauseManager) {
            this.name = name;
            this.pauseManager = pauseManager;
        }

        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    pauseManager.pauseIfNeeded();
                    System.out.println(name + " is running");
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

暂无
暂无

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

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