📜  JavaCountDownLatch和CyclicBarrier的区别(1)

📅  最后修改于: 2023-12-03 14:42:21.959000             🧑  作者: Mango

JavaCountDownLatch和CyclicBarrier的区别

JavaCountDownLatch

JavaCountDownLatch是一个非常基础的线程同步工具类,它可以让单个线程或多个线程一直等待,直到其他线程执行完毕后才能执行。它是通过计数器实现的,当计数器为0时,等待的线程会被唤醒继续执行。

下面是JavaCountDownLatch的一些特点:

  • 通过计数器实现线程之间的同步
  • 计数器初始值需要指定,调用countDown()方法可以将计数器减1
  • 调用await()方法的线程会一直阻塞,直到计数器为0

使用JavaCountDownLatch的示例代码:

CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        try {
            // 模拟耗时操作
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            latch.countDown();
        }
    }).start();
}

latch.await();
System.out.println("所有线程执行完毕");
CyclicBarrier

CyclicBarrier也是一种线程同步工具类,它的作用是让多个线程在一个栅栏前等待,直到所有线程都到达栅栏时才能继续执行。与JavaCountDownLatch不同,CyclicBarrier是通过计数器和释放信号实现的。

下面是CyclicBarrier的一些特点:

  • 当调用await()方法时,当前线程会先检查计数器,如果计数器为0,表示所有任务已经都到达栅栏,否则当前线程会被阻塞,直到所有任务都到达栅栏
  • 可以指定一个回调函数,在所有任务都到达栅栏后执行,回调函数在最后一个到达栅栏的线程中执行

使用CyclicBarrier的示例代码:

CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("所有线程执行完毕"));
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        try {
            // 模拟耗时操作
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "执行完毕,等待其他线程");
            barrier.await();
            System.out.println(Thread.currentThread().getName() + "继续执行");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }).start();
}
区别

JavaCountDownLatch和CyclicBarrier的区别主要有以下几点:

  1. 实现原理不同:JavaCountDownLatch是通过计数器实现的,CyclicBarrier是通过计数器和释放信号实现的;
  2. 使用场景不同:JavaCountDownLatch适用于一个线程等待其他线程执行完毕后再继续执行的情况;CyclicBarrier适用于多个线程互相等待后一起继续执行的情况;
  3. 回调函数不同:CyclicBarrier支持回调函数,在所有线程到达栅栏后执行,JavaCountDownLatch没有这个功能。

综上所述,JavaCountDownLatch和CyclicBarrier虽然都是线程同步工具类,但有其自身的特点和使用场景,需要根据具体的情况选择合适的工具类使用。