如何显式释放CountDownLatch

时间:2014-11-20 08:31:35

标签: java multithreading countdownlatch

有没有办法明确释放CountDownLatch - 意味着没有countDown()

例如:假设我正在等待100个线程进行countDown(),但如果出现故障,我想释放这个锁定而不再等待。我正想着getCount()关于闩锁&然后在循环中做countDown(),但这不是最佳方式。

有任何建议/想法吗?

5 个答案:

答案 0 :(得分:2)

CountDownLatch有一个重载的await()方法,它将时间时间单位作为输入,并在给定时间过后释放锁定< / p>

答案 1 :(得分:1)

为什么不使用等待超时?

boolean await(long timeout, TimeUnit unit);

如果指定的等待时间过去,则返回值false,否则在等待完成时返回true。

Abort countDownLatch.await() after time out

如果你想停止执行其他线程,如果任何线程失败 - 你需要一些额外的通信层。

例如:

AtomicBoolean kill = new AtomicBoolean(false);
CountDownLatch latch = new CountDownLatch(SOME_NUM);

class Task extends Runnable {
     public void run() {
         try {
              ....
              if (kill.get())
                  throw new Exception();
              ....
         } catch (Throwable throwable) {
            kill.set(true);
         } finally {
            countDownLatch.countDown();
         }
     }
}

如果您只想在Throwable上释放倒计时,无论其他进程如何,您都可以在异常循环中执行countDown

class Task extends Runnable {
     public void run() {
         try {
              ....
         } catch (Throwable throwable) {
            while(countDownLatch.getCount() != 0)
               countDownLatch.countDown();
         } finally {
            countDownLatch.countDown();
         }
     }
}

您可以合并2个countDown任务

CountDownLatch A = new CountDownLatch(1);
CountDownLatch B = new CountDownLatch(1);

class CountDownTracker extend Runnable {
     public void run() {
         B.await();
         A.countDown();
     }
}

class Task extends Runnable {
     public void run() {
         try {
              ....
         } catch (Throwable throwable) {
            A.countDown();
         } finally {
            B.countDown();
         }
     }
}

在这种情况下,A将在完成后完成,或任何任务失败。

等等......

答案 2 :(得分:0)

您可以使用Semaphore,它接近CountDownLatch并且它的impl有操作它的方法:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Semaphore.html

答案 3 :(得分:0)

除了其他答案:

它取决于“但是如果某些内容失败”意味着,但如果失败意味着您在工作线程中捕获了异常,那么您也可以在catch子句中倒计时。这当然会将countDown的含义从“成功处理”更改为“处理完成” - 所以你的代码必须处理这个......

答案 4 :(得分:0)

检查您的用例是否允许解决键盘交互式输入的问题。您可以期望在 System.in 中手动输入而不是 CoundDownLatch 或信号量:

Scanner sc = new Scanner(System.in);
sc.nextLine();

如果您在单元测试中需要这样做,请确保您的环境设置为读取用户输入,例如在帮助中使用 -Deditable.java.test.console=true 选项启动 IntelliJ Idea ->“编辑自定义 VM 选项...”