2011-12-01 79 views
0

当按下暂停按钮并重新运行播放按钮时,是否有办法等待执行程序池中的所有线程?我试过CountDownLatch,但我不知道我必须把它放在executor声明或run()方法之后?我没有关于threads.please多的信息可有人告诉我,我怎么能do.Thanksjava等待池中的所有线程

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


} 

回答

0

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

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

你的暂停和播放按钮应该得到的workerLock同步锁定,并设置暂停属性,调用notify()的workerLock。这将让工人暂停或继续按需。无论暂停/播放状态如何,执行程序总是“正在运行”。

编辑 您可以重构上面的代码变成自己的类,如下所示:

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。

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

我可以暂停,但无法恢复。您可以查看哪些错误? while(true)if(Frame.pause == true ){ 尝试Thread.currentThread()。wait(); } else { if(end == false){// not reach exit ...运行我的方法 – Ecrin

+0

您打电话给wait()on该线程,而应该在某些任意对象上调用wait(),wait()实际上是Obj中的一个方法等,而不是线程。被等待的对象应该被所有工作者共享,并且当状态改变时,摆动按钮应该在这个对象上调用notify()。 –

+0

是的,它的工作:)只是我改变了notifyAll()。当使用通知()它只是恢复当前线程。很多谢谢:) – Ecrin

0

可以等待所有的线程与完成:

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

+0

感谢ü。但是我怎样才能检查按钮是否按下了这个方法。我明白它可以根据确定的等待时间来工作。 – Ecrin

+0

@ user1073777:您必须将此代码放入暂停按钮的actionListener中。此代码将等待所有线程完成。 – Tudor

+0

确定它正在工作,但60秒,并开始继续本身。我想等待,直到播放按钮按下。我的意思是我不知道什么时候播放按钮按下,不能写一个时间而不是'60':( – Ecrin