Java 中 CountDownLatch 和 CyclicBarrier 有什么不同?

简介: Java 中 CountDownLatch 和 CyclicBarrier 有什么不同?v

以下都是Java的基础面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答建议收藏,经常温习查阅

7. Java 中 CountDownLatch 和 CyclicBarrier 有什么不同?

概念:

CountDownLatch 是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。简单来说:CountDownLatch 是一个计数器,可以保证线程之间的顺序执行把线程从并发状态调整为串行状态保证了线程的执行顺序。(只可以使用一次)

CyclicBarrier 是一个同步的辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。典型场景:可以用于多线程计算数据,最后合并计算结果。(可以多次使用)

分享一个直观的代码:

package com.javapub.test;

import java.util.concurrent.CountDownLatch;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/1 16:50
 * @Version: 1.0
 * @Description: countDownLatch 可以保证线程之间的顺序执行把线程从并发状态调整为串行状态保证了线程的执行顺序。
 * demo效果:当打印完B,再打印C。
 */

class ThreadA extends Thread {

    private CountDownLatch down;

    public ThreadA(CountDownLatch down) {
        this.down = down;
    }

    @Override
    public void run() {
        System.out.println("A");
        try {
            down.await();//相当于wait(),调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("C");
    }
}

class ThreadB extends Thread {
    private CountDownLatch down;

    public ThreadB(CountDownLatch down) {
        this.down = down;
    }

    @Override
    public void run() {
        System.out.println("B");
        System.out.println(down.getCount());
        down.countDown();//将count值减1
    }
}

public class Test {
    public static void main(String[] args) {
        CountDownLatch down = new CountDownLatch(1);//创建1个计数器
        new ThreadA(down).start();
        new ThreadB(down).start();
    }
}

/*输出
A
B
C
 */
package com.roundyuan.fanggateway.test;

import java.util.concurrent.CyclicBarrier;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/2 13:42
 * @Version: 1.0
 * @Description: CyclicBarrier
 */

public class CyclicBarrierDemo {

    static class TaskThread extends Thread {

        CyclicBarrier barrier;

        public TaskThread(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(getName() + " 到达栅栏 A");
                barrier.await();
                System.out.println(getName() + " 冲破栅栏 A");

                Thread.sleep(2000);
                System.out.println(getName() + " 到达栅栏 B");
                barrier.await();
                System.out.println(getName() + " 冲破栅栏 B");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int threadNum = 5;
        CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {

            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " 完成最后任务");
            }
        });

        for (int i = 0; i < threadNum; i++) {
            new TaskThread(barrier).start();
        }
    }
}

/*
Thread-3 到达栅栏 A
Thread-1 到达栅栏 A
Thread-4 到达栅栏 A
Thread-2 到达栅栏 A
Thread-0 到达栅栏 A
Thread-2 完成最后任务
Thread-2 冲破栅栏 A
Thread-0 冲破栅栏 A
Thread-4 冲破栅栏 A
Thread-3 冲破栅栏 A
Thread-1 冲破栅栏 A
Thread-4 到达栅栏 B
Thread-0 到达栅栏 B
Thread-2 到达栅栏 B
Thread-1 到达栅栏 B
Thread-3 到达栅栏 B
Thread-3 完成最后任务
Thread-3 冲破栅栏 B
Thread-0 冲破栅栏 B
Thread-4 冲破栅栏 B
Thread-1 冲破栅栏 B
Thread-2 冲破栅栏 B
 */

网上看到一个比较形象一个例子:

CountDownLatch:
宿管阿姨,晚上关宿舍大门睡觉,需要等到所有学生回寝,才能关门睡觉,学生之间不用相互等待,回寝就能睡觉。 (学生就是各个线程,宿管阿姨就是监听CountDownLatch为0后要执行的。)

CyclicBarrier:
家庭聚餐,等待家庭成员到齐才能开饭,家庭成员之间需要相互等待,直到最后一个到达,才能同时开饭。

目录
相关文章
|
6月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
63 0
|
2月前
|
Java
Java之CountDownLatch原理浅析
本文介绍了Java并发工具类`CountDownLatch`的使用方法、原理及其与`Thread.join()`的区别。`CountDownLatch`通过构造函数接收一个整数参数作为计数器,调用`countDown`方法减少计数,`await`方法会阻塞当前线程,直到计数为零。文章还详细解析了其内部机制,包括初始化、`countDown`和`await`方法的工作原理,并给出了一个游戏加载场景的示例代码。
Java之CountDownLatch原理浅析
|
4月前
|
算法 Java
JAVA并发编程系列(8)CountDownLatch核心原理
面试中的编程题目“模拟拼团”,我们通过使用CountDownLatch来实现多线程条件下的拼团逻辑。此外,深入解析了CountDownLatch的核心原理及其内部实现机制,特别是`await()`方法的具体工作流程。通过详细分析源码与内部结构,帮助读者更好地理解并发编程的关键概念。
|
4月前
|
Java
JAVA并发编程系列(9)CyclicBarrier循环屏障原理分析
本文介绍了拼多多面试中的模拟拼团问题,通过使用 `CyclicBarrier` 实现了多人拼团成功后提交订单并支付的功能。与之前的 `CountDownLatch` 方法不同,`CyclicBarrier` 能够确保所有线程到达屏障点后继续执行,并且屏障可重复使用。文章详细解析了 `CyclicBarrier` 的核心原理及使用方法,并通过代码示例展示了其工作流程。最后,文章还提供了 `CyclicBarrier` 的源码分析,帮助读者深入理解其实现机制。
|
5月前
|
Java
Java 中 CyclicBarrier 和 CountDownLatch 的区别
【8月更文挑战第22天】
144 4
|
6月前
|
Java 测试技术 开发者
Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用
Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用
83 11
|
6月前
|
设计模式 安全 Java
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
82 0
|
6月前
|
Java 开发者
Java面试题:解释Java内存模型中的内存可见性,解释Java中的线程池(ThreadPool)的工作原理,解释Java中的CountDownLatch和CyclicBarrier的区别
Java面试题:解释Java内存模型中的内存可见性,解释Java中的线程池(ThreadPool)的工作原理,解释Java中的CountDownLatch和CyclicBarrier的区别
36 0
|
6月前
|
Java 数据库连接
Java面试题:Java内存模型中的happens-before关系,Java中的ThreadLocal是如何工作的?Java中的CountDownLatch和CyclicBarrier的区别?
Java面试题:Java内存模型中的happens-before关系,Java中的ThreadLocal是如何工作的?Java中的CountDownLatch和CyclicBarrier的区别?
46 0
|
7月前
|
API
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
45 1