有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程java等待池中的所有线程

当按下暂停按钮和重新运行播放按钮时,是否有办法等待执行器池中的所有线程?我试过倒计时锁,但我不知道我必须把它放在执行器声明或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) 个答案

  1. # 1 楼答案

    你的机器人工作人员需要一种共享的线程安全方式来检查工作人员是否应该暂停或玩耍。在worker的run()方法中,如果线程已暂停,请等待有关此锁对象的通知。在循环时,或者无论工作人员做什么,定期检查锁的状态,如果需要,暂停工作人员

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

    您的pause and play按钮应该在workerLock上获得一个同步锁,设置pause属性,并在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的单个实例。将此实例传递给所有的机器人工作人员,并为要引用的挥杆暂停/播放动作保留一个引用。你的工作线程应该调用PauseIfNeed

    下面是一个使用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);
                    }
                }
            }
        }
    }