文章目录
一.简介
CountDownLatch和CyclicBarrier是jdk concurrent包下工具类,提供一种控制并发流程的工具。
二.CountDownLatch
构造类,常用api
public CountDownLatch(int count) { }; //参数count为计数值
public void await() throws InterruptedException { }; //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { }; //将count值减1
示例
线程池管理线程资源, join() 等待线程执行失效,CountDownLatch处理线程等待。
public class CountDownLatchTest {
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(2);
Thread t1 = new Thread(()->{
System.out.println("子线程:"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(()->{
System.out.println("子线程:"+Thread.currentThread().getName());
try {
Thread.sleep(10);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
t1.start();
t2.start();
countDownLatch.await();
System.out.println("2个子线程已经执行完毕");
System.out.println("继续执行主线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
CountDownLatch 计数器初始值等于2,之后计数器countDown 减一,通过 latch.await() 来实现对计数器等于0的等待。
三.CyclicBarrier
CyclicBarrier,让一组线程到达一个同步点后再一起继续运行,在其中任意一个线程未到达同步点,其他到达的线程均会被阻塞。
/**
* @Classname CyclicBarrierTest
* @Description TODO
* @Date 2020/11/7 15:13
* @Created by limeng
* 解决一组线程之间互相等待
* 让一组线程等待至某个状态之后再全部同步执行,叫做回环是因为当所有等待线程都被释放以后,CycilcBarrier可以被重用,我们暂且把这个状态叫做barrier
* ,当调用await()方法之后,线程就处于barrier了。
*
*
* parties 聚集数量,保证同步回调函数的数量
*/
public class CyclicBarrierTest {
public static void main(String[] args) {
int N = 5;
CyclicBarrier cyclicBarrier = new CyclicBarrier(N);
ThreadPoolExecutor pool = ThreadPool.newFixedThreadPool(10, "CyclicBarrierTest", false);
System.out.println(cyclicBarrier.getParties());
for (int i = 0; i < N; i++) {
pool.execute(new Writer(cyclicBarrier));
}
}
static class Writer implements Runnable{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getName()+" 正在写入数据");
try {
Thread.sleep(1000);
System.out.println("线程:"+Thread.currentThread().getName() + "写完");
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有线程写入完毕,继续处理其他任务");
}
}
}
四.总结
CountDownLatch 主要用来解决一个线程等待多个线程的场景。
CyclicBarrier是一组线程之间互相等待。
CountDownLatch计数器是不能循环利用,也就是说一旦计数器减到0,在有线程调用await(),该线程会直接通过,但CyclicBarrier的计数器是可以循环利用的,而且具备自动重置的功能,一旦计数器减到0会自动重置到你设置的初始值,除此之外,CyclicBarrier还可以设置回调函数。
参考
《Java并发编程实战》
公众号
微信号:bigdata_limeng