线程计数器countdownlatch和cyclicbarrier
线程计数器 CountDownLatch CyclicBarrer
使用场景 : 对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步
区别:
CountDownLatch | CyclicBarrer |
-1方式计数 | +1方式技术 |
当计数减为0时释放所有等待的线程 | 当计数达到指定值时释放所有等待线程 |
计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开始 |
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞 |
线程状态不同 :countDown()方法所在线程进行 -1 操作 ,await()方法所在线程阻塞,直到计数器减为0才执行 | 线程状态相同:都在做+1操作,等待达到指定值 |
CountDownLatch :
countDownLatch 要等所有的业务做完在进行countDown()操作
public static void countDownLatchTest() {
CountDownLatch downLatch = new CountDownLatch(5);
// 循环启动5个线程
for (int i = 5; i >= 1; i--) {
final int num = i;
new Thread(() -> {
System.out.println("线程: " + Thread.currentThread().getName() + " 开始执行 ");
System.out.println("线程: " + Thread.currentThread().getName() + " 执行结束" );
downLatch.countDown();
}, String.valueOf(num)).start();
}
try {
// 阻塞等待计数器减为0
downLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("await()方法后代码执行");
}
执行结果
CyclicBarrier :
public static void cyclicBarrayTest() {
CyclicBarrier barrier = new CyclicBarrier(5, () -> {
//当计步器达到五时 执行这里的预操作
System.out.println("执行线程");
});
for (int i = 1; i <= 5; i++) {
final int num = i;
new Thread(() -> {
System.out.println("线程: " + Thread.currentThread().getName() + "开始执行");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
// 当计数器达到五时执行此代码
System.out.println("线程: " + Thread.currentThread().getName() + "结束执行");
}, String.valueOf(num)).start();
}
}
执行结果