【问题标题】:In Java, how can I wait for one of multiple threads to exit?在 Java 中,如何等待多个线程之一退出?
【发布时间】:2014-08-03 04:20:35
【问题描述】:

在 Java 中,您可以使用 Thread.join() 等待线程退出

是否有类似的方法可以让您等待线程列表中的任何线程退出?

这类似于在任何子进程退出时返回的wait(2) Unix 系统调用。

【问题讨论】:

  • 使用某种Executor 并调用invokeAll,这将阻塞直到所有任务完成
  • 这里是 code 使用 CoundDownLatch。
  • 从设计的角度来看,我不太理解这一点。等待 any 线程。假设你启动了 5 个线程,你想等待 any 线程退出? CountdownLatch 确实可以使用,您可以最初将计数设置为1 并减少所有线程中的计数,但是为什么呢?

标签: java multithreading


【解决方案1】:

您可以使用java.util.concurrent 包中的CountDownLatch。像这样的:

CountDownLatch c = new CountDownLatch(3);
...
c.await();

【讨论】:

    【解决方案2】:

    如果您使用的是 Java 1.5 或更高版本,请查看 CountDownLatch

    【讨论】:

      【解决方案3】:

      假设您需要提交一组后台任务,并且您希望等待每个任务都可用并处理其结果,但您不想在开始处理之前阻止等待所有任务。您可以使用ExecutorCompletionService。

      import java.util.concurrent.Callable;
      import java.util.concurrent.CompletionService;
      import java.util.concurrent.ExecutorCompletionService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ThreadFactory;
      
      public final class Main {
      
          public static void main(String[] args) throws Exception {
              // Bootstrap CompletionService backed by a pool of 5 daemon threads.
              CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(
                  Executors.newFixedThreadPool(5, new ThreadFactory() {
                      @Override
                      public Thread newThread(Runnable r) {
                          Thread t = new Thread(r);
                          t.setDaemon(true);
                          return t;
                      }
                  }));
      
              // Submit 20 contrived Callables that just return a monotonically
              // increasing integer.  Introduce a random sleep just to make the
              // multi-threading effects more visible.
              int n = 20;
              for (int i = 0; i < n; ++i) {
                  final Integer result = i;
                  // The submit call does not block here.
                  cs.submit(new Callable<Integer>() {
                      @Override
                      public Integer call() {
                          try {
                              Thread.sleep((long)(Math.random() * 10));
                              return result;
                          } catch (InterruptedException e) {
                              return null;
                          }
                      }
                  });
              }
      
              for (int i = 0; i < n; ++i) {
                  // The take call blocks here until the next Callable finishes.
                  Integer result = cs.take().get();
                  if (result != null) {
                      System.out.println(result);
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        CountdownLatch 不错,但 Semaphore 可重复使用。

        final Semaphore semaphore = new Semaphore(0);
        
        class WaitedForTask implements Runnable {
            @Override
            public void run() {
                try {
                    doSomethingUseful();
                } finally {
                    semaphore.release();
                }
            }
        }
        
        void runnem() throws InterruptedException {
            Thread[] thread = new Thread[NUMTHREADS];
            for (int i=0 ; i<NUMTHREADS ; i++) {
                thread[i] = new Thread(new WaitedForTask());
                thread[i].start();
            }
            for (int i=0 ; i<NUMTHREADS ; i++) {
                semaphore.acquire();
                System.out.println("Another one bites the dust.");
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-10
          • 1970-01-01
          • 2011-06-02
          • 2010-09-22
          • 2015-03-31
          • 1970-01-01
          相关资源
          最近更新 更多