2

有没有什么方法可以显式释放CountDownLatch- 意味着没有 do countDown()

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

有什么建议/想法吗?

4

5 回答 5

2

The CountDownLatch has an overloaded await() method which takes time and time unit as inputs and releases the lock once the given time elapses

于 2014-11-20T08:33:53.140 回答
1

为什么不直接使用等待超时?

boolean await(long timeout, TimeUnit unit);

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

超时后中止 countDownLatch.await()

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

例如:

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 的倒计时,而不管其他进程,您可以在 Exception 的循环中执行 countDown

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

您可以组合 2 个倒计时任务

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 将在完成或任何任务失败后完成。

等等...

于 2014-11-20T08:37:16.910 回答
1

You could use a Semaphore, which is close to a CountDownLatch and it's impl has methods for manipulating it: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Semaphore.html

于 2014-11-20T08:34:03.703 回答
0

除了其他答案:

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

于 2014-11-20T09:03:50.700 回答
0

检查您的用例是否允许通过键盘交互输入来解决问题。然后,您可以期望在 System.in 中手动输入,而不是 CoundDownLatch 或 Semaphore:

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

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

于 2021-05-17T19:25:34.507 回答