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:
家庭聚餐,等待家庭成员到齐才能开饭,家庭成员之间需要相互等待,直到最后一个到达,才能同时开饭。

目录
相关文章
|
13天前
|
API
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅栏) Semaphore(信号量)-
13 1
|
21天前
|
存储 并行计算 Java
Java8中JUC包同步工具类深度解析(Semaphore,CountDownLatch,CyclicBarrier,Phaser)
Java8中JUC包同步工具类深度解析(Semaphore,CountDownLatch,CyclicBarrier,Phaser)
18 2
|
2天前
|
Java
java使用CountDownLatch将一个任务拆解后合并处理
java使用CountDownLatch将一个任务拆解后合并处理
5 0
|
1月前
|
Java
Java一分钟之-并发编程:线程间通信(Phaser, CyclicBarrier, Semaphore)
【5月更文挑战第19天】Java并发编程中,Phaser、CyclicBarrier和Semaphore是三种强大的同步工具。Phaser用于阶段性任务协调,支持动态注册;CyclicBarrier允许线程同步执行,适合循环任务;Semaphore控制资源访问线程数,常用于限流和资源池管理。了解其使用场景、常见问题及避免策略,结合代码示例,能有效提升并发程序效率。注意异常处理和资源管理,以防止并发问题。
42 2
|
1月前
|
数据采集 Java API
Java并发基础:CyclicBarrier全面解析!
CyclicBarrier的优点在于实现了线程间的相互等待与协同,确保所有线程在达到预定屏障点后才能继续执行,它支持屏障的重复使用,非常适合多轮次的任务同步,此外,CyclicBarrier还允许在屏障点执行特定操作,为复杂的多线程协作提供了便利。
Java并发基础:CyclicBarrier全面解析!
|
1月前
|
Java API
JAVA同步锁CountDownLatch
JAVA同步锁CountDownLatch
|
1月前
|
Java
面试题2:Java中CycliBarriar和CountdownLatch区别
面试题2:Java中CycliBarriar和CountdownLatch区别
|
7月前
|
Java
Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作
Java 利用JUC CountDownLatch 线程池Executors 实现多线程操作 业务场景:某个业务操作非常耗时,但又必须等这个操作结束后才能进行后续操作
55 0
|
9月前
|
Java 开发工具 git
【Java多线程】如何正确使用倒计时协调器:CountDownLatch
CountDownLatch可以用来实现一个或者多个(注意可以有多个)线程,等待其他线程完全一组特定的操作后,才开始继续执行的操作,这些特定的操作被称作先决条件。
111 2
|
9月前
|
Java 开发工具 git
【Java多线程】如何正确使用循环栅栏CyclicBarrier
想象一个这样的场景,我们在打王者荣耀/英雄联盟的时候,都会有一个匹配机制,需要10个人都加载完成后,大家才能一起进入游戏,不然会出现大家进入游戏的时间不一致的情况,这个时候就可以使用CyclicBarrier来实现。