簡體   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