Java 并发编程实战学习笔记——CountDownLatch的使用
2013-11-12 18:00
906 查看
public class CountDownLatchextends Object
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化
CountDownLatch。由于调用了
countDown()方法,所以在当前计数到达零之前,
await方法会一直受阻塞。之后,会释放所有等待的线程,
await的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用
CyclicBarrier。
CountDownLatch是一个通用同步工具,它有很多用途。将计数 1 初始化的
CountDownLatch用作一个简单的开/关锁存器,或入口:在通过调用
countDown()的线程打开入口前,所有调用
await的线程都一直在入口处等待。用 N 初始化的
CountDownLatch可以使一个线程在
N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。
CountDownLatch的一个有用特性是,它不要求调用
countDown方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个
await。
示例用法: 下面给出了两个类,其中一组 worker 线程使用了两个倒计数锁存器:
第一个类是一个启动信号,在 driver 为继续执行 worker 做好准备之前,它会阻止所有的 worker 继续执行。
第二个类是一个完成信号,它允许 driver 在完成所有 worker 之前一直等待。
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 来描述每个部分,然后将所有 Runnable 加入到 Executor 队列。当所有的子部分完成后,协调线程就能够通过 await。(当线程必须用这种方法反复倒计数时,可改为使用
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()之前的操作 happen-before 紧跟在从另一个线程中对应
await()成功返回的操作。
相关文章推荐
- [置顶] java 并发编程实战书籍学习 第五章,CountDownLatch,FutureTask,CyclicBarrier,Semaphore学习
- Java 并发编程实战学习笔记——串行任务转并行任务
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
- Java并发学习笔记(14) 闭锁(CountDownLatch)
- Java并发编程深入学习——CountDownLatch、CyclicBarrier和Semaphore
- Java并发编程之2——同步工具类的使用(CountDownLatch,CyclicBarrier,BlockungQueue,Semaphore)
- 并发编程实战学习笔记(六)——线程池的使用
- 深入学习java并发编程:CountDownLatch、CyclicBarrier
- Java并发编程:CountDownLatch的使用以及一个容易踩到的陷阱
- 《Java 7 并发编程指南》学习概要 (3)Semaphore, CountDownLatch, CyclicBarrier , Phaser, Exchanger
- Java 并发编程实战学习笔记
- 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程
- Java 并发编程实战学习笔记——寻找可强化的并行性
- Java 并发编程深入学习——CopyOnWrite容器使用和原理分析
- java泛型编程学习 笔记一:为什么要使用泛型
- [学习笔记]java并发编程目录
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore(转)
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
- Java并发编程之CountDownLatch
- java并发编程实战学习(3)--基础构建模块