【问题标题】:Better way to signal other thread to stop?更好的方式来通知其他线程停止?
【发布时间】:2011-10-15 03:19:41
【问题描述】:

启动了几个工作线程,需要通知他们停止。由于某些线程会在下一轮工作之前休眠一段时间,因此需要一种即使在它们处于休眠状态时也能通知它们的方法。

如果是 Windows 编程,我可以使用事件和等待函数。在 Java 中,我使用计数为 1 的 CountDownLatch 对象来执行此操作。它可以工作但感觉不优雅,尤其是我必须检查计数值以查看是否需要退出:

run(){
    while(countDownLatch.count()>0){
            //working
            // ...
            countDownLatch.wait(60,TimeUnit.SECONDS);
    }
}

Semaphore 是另一种选择,但也感觉不太对。我想知道有没有更好的方法来做到这一点?谢谢。

【问题讨论】:

  • 这不是您正在寻找的答案,但您应该使用线程池 (java.util.concurrent)。我几乎可以肯定他们可以做你想做的事,而且没有错误,你可以利用你的时间来开发其他东西。
  • 你想停止所有线程,还是只想停止几个?
  • @Moonbeam 我需要单独停止它们,所以线程池似乎不是一个可行的解决方案。
  • @HourseArmor,如果不是所有给出的答案都是合适的,那么大多数都是合适的。

标签: java


【解决方案1】:

另一个最好的方法是使用interrupt( ) 方法。

例如,线程如何使用此信息来确定它是否应该终止:

public class TestAgain extends Thread {
           //  ...
           //  ...
         public void run( ) {
               while (!isInterrupted( )) {
                  //    ...
                     }
                 }     
           }

【讨论】:

    【解决方案2】:

    为了有一个线程池,我会使用ExecutorServiceScheduledExecutorService 来处理延迟/周期性任务。

    当你想让工人停下来时,你可以使用

    executorService.shutdown();
    

    【讨论】:

    • 他必须使用 shutdownNow()。
    【解决方案3】:

    最好的方法是interrupt()工作线程。


    Thread t = new Thread(new Runnable(){
        @Override
        public void run(){
            while(!Thread.currentThread().isInterrupted()){
                //do stuff
                try{
                    Thread.sleep(TIME_TO_SLEEP);
                }catch(InterruptedException e){
                    Thread.currentThread().interrupt(); //propagate interrupt
                }
            }
        }
    });
    t.start();
    

    只要您有对t 的引用,“停止”t 所需要做的就是调用t.interrupt()

    【讨论】:

    • 我喜欢你提到的再次中断,因为中断标志被清除了。
    【解决方案4】:

    好办法是interrupt()线程,和线程内循环一样

    try {
       while (!Thread.interrupted()) {
           ...
       }
    } catch (InterruptedException e) {
       // if interrupted in sleep
    }
    

    在打断时记住这两种情况:

    • 如果你 sleepwaitInterruptedException 将被抛出;
    • 在其他情况下,将为您必须自己检查的线程设置中断标志。

    【讨论】:

      【解决方案5】:

      使用内置的线程中断框架。要停止工作线程调用workerThread.interrupt(),这将导致某些方法(如 Thread.sleep())抛出一个中断的异常。如果您的线程不调用可中断方法,那么您需要检查中断状态。

      在工作线程中:

      run() {
          try {
              while(true) {
                  //do some work
                  Thread.sleep(60000);
              }
          }
          catch(InterruptedException e) {
              //told to stop working
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        • 1970-01-01
        • 2023-04-06
        相关资源
        最近更新 更多