线程的并发工具类CountDownLatch和CyclicBarrier
1.CountDownLatch简介
1.CountDownLatch是具有synchronized机制的一个工具,目的是让一个或者多个线程等待,直到其他线程的一系列操作完成。
2.闭锁,CountDownLatch 这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动 所有的框架服务之后再执行。
3.CountDownLatch 是通过一个计数器来实现的,计数器的初始值为初始任务 的数量。每当完成了一个任务后,计数器的值就会减 1 (CountDownLatch.countDown()方法)。当计数器值到达 0 时,它表示所有的已 经完成了任务,然后在闭锁上等待 CountDownLatch.await()方法的线程就可以恢 复执行任务。
2.CountDownLatch相关api
//返回当前的计数count值 public long getCount() { return sync.getCount(); } /*调用此方法后,会减少计数count的值。 递减后如果为0,则会释放所有等待的线程*/ public void countDown() /*调用CountDownLatch对象的await方法后。 会让当前线程阻塞,直到计数count递减至0。*/ public void await() throws InterruptedException /*同时await还提供一个带参数和返回值的方法。 如果计数count正常递减,返回0后,await方法会返回true并继续执行后续逻辑。 或是,尚未递减到0,而到达了指定的时间间隔后,方法返回false。 如果时间小于等于0,则此方法不执行等待。*/ public boolean await(long timeout, TimeUnit unit) throws InterruptedException
注意事项:
1.在定义扣减数时,不需要和初始线程数保持一致,但一般会大于等于初始线程数,扣减数和代码中调用countdown()的次数保持一致;
2.在调用await()方法后,线程会阻塞,以下两种情况会脱离阻塞状态:
(1)、调用countDown()方法,将计数count递减至0。
(2)、当前线程被其他线程打断。
3.countDownLatch.countDown();
这一句话尽量写在finally中,或是保证此行代码前的逻辑正常运行,因为在一些情况下,出现异常会导致无法减一,然后出现死锁。
CountDownLatch 是一次性使用的,当计数值在构造函数中初始化后,就不能再对其设置任何值,当 CountDownLatch 使用完毕,也不能再次被使用。
3.CountDownLatch应用场景
(1)实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。
(2)开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。
(3)死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁
4.CyclicBarrier简介
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做 的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一 个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
5.CyclicBarrier的api
//该参数表示屏障拦截的线程数量 public CyclicBarrier(int parties) { this(parties, null); } //在线程全部到达屏障时,需要先执行barrierAction才可让所有阻塞的线程继续运行 public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } //每个线程通过调用该方法告诉CyclicBarrier我已经到达屏障,然后进行阻塞,等待所有线程都到达屏障才同时释放 public int await() throws InterruptedException, BrokenBarrierException { try { return dowait(false, 0L); } catch (TimeoutException toe) { throw new Error(toe); // cannot happen } } //使CyclicBarrier回到初始状态,所以称之为可循环屏障 public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } }
6.CyclicBarrier的应用场景
CyclicBarrier可以用于多线程计算数据,最后合并计算结果的应用场景。比如现在需要计算10个人12个月内的工资详细,可以将线程分为10个,分别计算每个人的工资,最后,再用barrierAction将这些线程的计算结果进行整合,得出最后结果。
4.两者的区别
1.CountDownLatch 的计数器只能使用一次,而 CyclicBarrier 的计数器可以反复 使用。
2.CountDownLatch.await 一般阻塞工作线程,所有的进行预备工作的线程执行 countDown,而 CyclicBarrier 通过工作线程调用 await 从而自行阻塞,直到所有工 作线程达到指定屏障,再大家一起往下走。
3.在控制多个线程同时运行上,CountDownLatch 可以不限线程数量,而 CyclicBarrier 是固定线程数。
同时,CyclicBarrier 还可以提供一个 barrierAction,合并多线程计算结果。
4.CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以5.CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次
6.CyclicBarrier还提供getNumberWaiting(可以获得CyclicBarrier阻塞的线程数量)、isBroken(用来知道阻塞的线程是否被中断)等方法。
7.CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。
- java并发中的协同工具类介绍-CountDownLatch-CyclicBarrier-Semphone-Exchanger
- 学会使用线程的并发工具类(ForkJoin、CountdownLatch、CyclicBarrier、Semaphore、Exchange)
- 线程的并发工具类 --- CyclicBarrier
- Java并发工具类CountDownLatch和CyclicBarrier
- 【死磕Java并发】—- J.U.C之并发工具类:CyclicBarrier
- java并发编程2.2并发工具类——CountDownLatch和CyclicBarrier使用及比较
- CountDownLatch和CyclicBarrier模拟同时并发请求
- [Java并发包学习五]CountDownLatch和CyclicBarrier介绍
- 【死磕Java并发】—- J.U.C之并发工具类:CyclicBarrier
- CyclicBarrier并发工具类
- java多线程解说【拾陆】_并发工具类:CyclicBarrier
- java高并发程序设计总结五:jdk并发包其他同步控制工具类:ReadWriteLock/CountDownLatch/CyclicBarrier/LockSupport
- Java 并发:CyclicBarrier 实现线程协作控制
- Java/Android多线程并发、同步,线程之间通信,主、子线程的一些问题(CountDownLatch、CyclicBarrier和Semaphore)
- 并发工具类:CountDownLatch、CyclicBarrier、Semaphore
- Java多线程—JAVA中并发的工具类CountDownLatch、CyclicBarrier、Semaphore、Exchanger
- 【死磕Java并发】-----J.U.C之并发工具类:CyclicBarrier
- 并发包下常见的同步工具类详解(CountDownLatch,CyclicBarrier,Semaphore)
- java并发包线程同步 - CountDownLatch与CyclicBarrier比较学习
- Java并发:同步工具类详解(CountDownLatch、CyclicBarrier、Semaphore)