Java并发编程:CountDownLatch线程等待同步辅助类
原文地址:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
java.util.concurrent中
CountDownLatch类
- java.lang.Object继承
- java.util.concurrent.CountDownLatch
-
公共类CountDownLatch 扩展了Object
允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
-
A
CountDownLatch
用给定的计数初始化。由于await
方法的调用,方法阻塞直到当前计数达到零countDown()
,之后释放所有等待的线程并await
立即返回任何后续的调用 。这是一次性现象 - 计数无法重置。如果您需要重置计数的版本,请考虑使用CyclicBarrier
。A
CountDownLatch
是一种通用的同步工具,可用于多种用途。甲CountDownLatch
一个的计数初始化作为一个简单的开/关锁存器,或门:所有线程调用await
,直到它被一个线程调用开在栅极等待countDown()
。一个CountDownLatch
初始化为ň 可以用来做一个线程等待,直到ň线程完成一些动作,或某些动作已经完成N次。a的一个有用属性
CountDownLatch
是它不需要线程调用countDown
等待计数在继续之前达到零,它只是阻止任何线程继续经过await
直到所有线程都可以通过。示例用法:这是一对类,其中一组工作线程使用两个倒计时锁存器:
- 第一个是启动信号,阻止任何工人继续工作,直到驱动程序准备好继续进行;
- 第二个是完成信号,允许驾驶员等到所有工人完成。
class Driver { // ... void main() throws InterruptedException { CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // create and start threads new Thread(new Worker(startSignal, doneSignal)).start(); doSomethingElse(); // don't let run yet startSignal.countDown(); // let all threads proceed doSomethingElse(); doneSignal.await(); // wait for all to finish } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { this.startSignal = startSignal; this.doneSignal = doneSignal; } public void run() { try { startSignal.await(); doWork(); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } }
另一个典型的用法是将问题分成N个部分,用执行该部分的Runnable描述每个部分并对锁存器进行倒计时,并将所有Runnables排队到Executor。当所有子部件都完成后,协调线程将能够通过等待。(当线程必须以这种方式重复倒计时,而是使用a
CyclicBarrier
。)class Driver2 { // ... void main() throws InterruptedException { CountDownLatch doneSignal = new CountDownLatch(N); Executor e = ... for (int i = 0; i < N; ++i) // create and start threads e.execute(new WorkerRunnable(doneSignal, i)); doneSignal.await(); // wait for all to finish } } class WorkerRunnable implements Runnable { private final CountDownLatch doneSignal; private final int i; WorkerRunnable(CountDownLatch doneSignal, int i) { this.doneSignal = doneSignal; this.i = i; } public void run() { try { doWork(i); doneSignal.countDown(); } catch (InterruptedException ex) {} // return; } void doWork() { ... } }
内存一致性影响:在计数达到零之前,调用之前的线程中的 操作
countDown()
发生在从await()
另一个线程中的对应成功返回之后的操作 之前。以来:
1.5
-
方法摘要
-
构造函数摘要
构造函数 构造函数和描述 CountDownLatch(int count)
CountDownLatch
使用给定计数构造初始化。
-
方法细节
-
等待
除非线程被中断,否则导致当前线程等待锁存器倒计数到零。public void await() 抛出InterruptedException
如果当前计数为零,则此方法立即返回。
如果当前计数大于零,则当前线程将被禁用以进行线程调度,并且在发生以下两种情况之一之前处于休眠状态:
- 由于
countDown()
方法的调用,计数达到零 ; 要么 - 其他一些线程会中断 当前线程。
如果当前线程:
- 在进入此方法时设置其中断状态; 要么
- 在等待时 被打断
InterruptedException
抛出 然后清除当前线程的中断状态。抛出:
InterruptedException
- 如果当前线程在等待时被中断 - 由于
-
等待
导致当前线程等待,直到锁存器倒计数到零,除非线程被中断,或者指定的等待时间过去。public boolean await(long timeout, TimeUnit unit) 抛出InterruptedException
如果当前计数为零,则此方法立即返回值
true
。如果当前计数大于零,则当前线程因线程调度而被禁用,并且在发生以下三种情况之一之前处于休眠状态:
- 由于
countDown()
方法的调用,计数达到零 ; 要么 - 其他一些线程会中断 当前线程; 要么
- 指定的等待时间过去了。
如果计数达到零,则该方法返回值
true
。如果当前线程:
- 在进入此方法时设置其中断状态; 要么
- 在等待时 被打断
InterruptedException
抛出 然后清除当前线程的中断状态。如果指定的等待时间过去,则
false
返回该值。如果时间小于或等于零,则该方法将不会等待。参数:
timeout
- 等待的最长时间unit
-timeout
参数的时间单位返回:
true
如果计数达到零并且false
在计数达到零之前等待时间已过去抛出:
InterruptedException
- 如果当前线程在等待时被中断 - 由于
-
倒数
减少锁存器的计数,如果计数达到零则释放所有等待的线程。public void countDown()
如果当前计数大于零,则递减。如果新计数为零,则重新启用所有等待线程以进行线程调度。
如果当前计数等于零,则没有任何反应。
-
getCount将
返回当前计数。public long getCount()
此方法通常用于调试和测试目的。
返回:
目前的数量
-
-
构造函数详细信息
-
CountDownLatch
public CountDownLatch(int count)
CountDownLatch
使用给定计数构造初始化。参数:
count
-countDown()
线程可以通过之前必须调用的次数await()
抛出:
IllegalArgumentException
- 如果count
是否定的
-
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
2016-05-06 Ubuntu 16.04 LTS 正式发布:系统将持续更新5年