简体   繁体   English

Java等待池中的所有线程

[英]java wait all threads in pool

Is there a way to wait all threads in executor pool when pause button pressed and rerun play button pressed? 当按下暂停按钮并重新运行播放按钮时,是否有办法等待执行程序池中的所有线程? I tried CountDownLatch but I dont know I must put it after executor declaration or in run () method? 我尝试了CountDownLatch,但我不知道我必须在执行程序声明之后还是在run()方法中放置它? I dont have much information about threads.please can someone tell me how I can do.Thanks 我没有关于线程的太多信息。请有人可以告诉我我该怎么做。

 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();
    }


}

Your Robot worker needs a shared thread-safe way to check whether workers should be paused or playing. 您的机器人工作人员需要一种共享的线程安全方式来检查工作人员是否应该暂停或玩耍。 In the run() method of your worker, if the thread is paused, wait for notification on this lock object. 在工作程序的run()方法中,如果线程已暂停,请等待此锁对象的通知。 While looping, or whatever it is the worker does, periodically check the state of the lock, and pause the worker if needed. 在循环或执行工作时,定期检查锁定状态,并在需要时暂停工作。

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

Your pause and play button should get a synchronized lock on the workerLock, and set the paused property, and call notify() on the workerLock. 您的暂停和播放按钮应该在workerLock上获得同步锁,并设置暂停的属性,然后在workerLock上调用notify()。 This will let the workers pause or continue as needed. 这将使工作人员根据需要暂停或继续。 The Executor is always "running", regardless of the paused/playing state. 不管暂停/播放状态如何,执行器始终处于“运行中”状态。

EDIT You can refactor the above code into its own class, as follows: 编辑您可以将上述代码重构为自己的类,如下所示:

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();
    }
}

Create a single instance of WorkerPauseManager. 创建一个WorkerPauseManager实例。 Pass this instance to all your Robot workers, and keep a reference for the swing pause/play actions to reference. 将此实例传递给您的所有Robot工人,并保留参考作为挥杆暂停/播放动作的参考。 Your worker thread should call pauseIfNeeded. 您的工作线程应调用pauseIfNeeded。

Here's an SCCE using the WorkerPauseManager: 这是使用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