CountDownLatch减法计数器
- CountDownLatch 允许一个或多个线程等待一些特定的操作完成,而这些操作是在其它的线程中进行的
- CountDownLatch 构造函数中有一个 count 参数,表示有多少个线程需要被等待。其他线程调用countDown()方法,每调用一次 countDown 方法就表示有一个被等待的线程到达,count 变为 0 时,latch(闩shuan锁)就会被打开,处于等待状态的那些线程接着可以执行
- 一个线程中可以调用多次countDown()
- CountDownLatch 是一次性使用的,没有为 count 变量提供 set 的方法
- CountDownLatch非常适合于对任务进行拆分,使其并行执行,总的执行时间将决定于执行最慢的任务
import java.util.concurrent.CountDownLatch;
class MyCountDownLatch {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
new Thread(()->{
try {
countDownLatch.await();
// 可以多个线程一起等待
System.out.println("over1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
for (int i = 0; i < 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
// 计数器减一
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
// 等待计数器归零才会往下执行
countDownLatch.await();
System.out.println("over2");
}
}
CyclicBarrier栅栏
- CyclicBarrier也叫同步屏障,在JDK1.5被引入,可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,所以被阻塞的线程才能继续执行。
- CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置,可以使用多次,所以CyclicBarrier能够处理更为复杂的场景;
- CyclicBarrier还提供了一些其他有用的方法,比如getNumberWaiting()方法可以获得CyclicBarrier阻塞的线程数量,isBroken()方法用来了解阻塞的线程是否被中断;
- CountDownLatch允许一个或多个线程等待一组事件的产生,而CyclicBarrier用于等待其他线程运行到栅栏位置。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class MyCyclicBarrier {
public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("over");
});
for (int i = 0; i < 7; i++) {
final int temp = i;
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " " + temp);
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}