有没有办法明确释放CountDownLatch
- 意味着没有countDown()
。
例如:假设我正在等待100个线程进行countDown()
,但如果出现故障,我想释放这个锁定而不再等待。我正想着getCount()
关于闩锁&然后在循环中做countDown()
,但这不是最佳方式。
有任何建议/想法吗?
答案 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 选项...”