CountDownLatch和CyclicBarrier

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();
        }
    }
}
posted @ 2021-10-30 15:32  n1ce2cv  阅读(73)  评论(0编辑  收藏  举报