Java ждать всех потоков в пуле - PullRequest
0 голосов
/ 01 декабря 2011

Есть ли способ ожидания всех потоков в пуле исполнителей, когда нажата кнопка паузы и нажата кнопка повторного запуска? Я пробовал CountDownLatch, но я не знаю, должен ли я ставить его после объявления executor или в методе 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();
    }


}

Ответы [ 2 ]

0 голосов
/ 01 декабря 2011

Ваш рабочий-робот должен использовать общий потокобезопасный способ проверки, должны ли рабочие быть приостановлены или играть. В методе run () вашего работника, если поток приостановлен, дождитесь уведомления об этом объекте блокировки. Во время зацикливания, или что-либо еще, что делает работник, периодически проверяйте состояние блокировки и при необходимости останавливайте работника.

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

Ваша кнопка паузы и воспроизведения должна получить синхронизированную блокировку для workerLock, установить свойство paused и вызвать notify () для workerLock. Это позволит рабочим сделать паузу или продолжить работу по мере необходимости. Исполнитель всегда «работает» независимо от состояния паузы / воспроизведения.

EDIT Вы можете преобразовать приведенный выше код в его собственный класс следующим образом:

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. Передайте этот экземпляр всем своим рабочим-роботам и сохраните ссылку для действий паузы / воспроизведения свинга для ссылки. Ваш рабочий поток должен вызвать pauseIfNeeded.

Вот SCCE, использующий WorkerPauseManager:

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);
                }
            }
        }
    }
}
0 голосов
/ 01 декабря 2011

Вы можете дождаться окончания всех потоков:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...