CyclicBarrier:人齐了,老司机就发车了!(2)

简介: CyclicBarrier:人齐了,老司机就发车了!(2)

CyclicBarrier VS CountDownLatch


CountDownLatch:一个或者多个线程,等待另外 N 个线程完成某个事情之后才能执行。

CountDownLatch 就像玩王者农药开局的加载一样,所有人要等待其他人都加载 100% 之后才能开始游戏。


微信图片_20220120172356.jpg


CyclicBrrier:N 个线程相互等待,直到有足够数量的线程都到达屏障点之后,之前等待的线程就可以继续执行了。


CyclicBrrier 就像老司机开车一样,如果车上还有空余的座位,那么所有人都得等着,直到座位被坐满之后,老司机才会发车。


微信图片_20220120172415.gif



CyclicBarrier使用


import java.util.Date;
import java.util.Random;
import java.util.concurrent.*;
publicclass CyclicBarrierExample {
    public static void main(String[] args) {
        // 创建 CyclicBarrier
        final CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
            @Override
            public void run() {
                System.out.println("人满了,准备发车:" + new Date());
            }
        });
        // 线程调用的任务
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // 生成随机数 1-3
                int randomNumber = new Random().nextInt(3) + 1;
                // 进入任务
                System.out.println(String.format("我是:%s 再走:%d 秒就到车站了,现在时间:%s",
                        Thread.currentThread().getName(), randomNumber, new Date()));
                try {
                    // 模拟执行
                    TimeUnit.SECONDS.sleep(randomNumber);
                    // 调用 CyclicBarrier
                    cyclicBarrier.await();
                    // 任务执行
                    System.out.println(String.format("线程:%s 上车,时间:%s",
                            Thread.currentThread().getName(), new Date()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        };
        // 创建线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        // 执行任务 1
        threadPool.submit(runnable);
        // 执行任务 2
        threadPool.submit(runnable);
        // 执行任务 3
        threadPool.submit(runnable);
        // 执行任务 4
        threadPool.submit(runnable);
        // 等待所有任务执行完终止线程池
        threadPool.shutdown();
    }
}
相关文章
|
5月前
|
安全 Java 程序员
惊呆了!Java多线程里的“synchronized”竟然这么神奇!
【6月更文挑战第20天】Java的`synchronized`关键字是解决线程安全的关键,它确保同一时间只有一个线程访问同步代码。在案例中,`Counter`类的`increment`方法如果不加同步,可能会导致竞态条件。通过使用`synchronized`方法或语句块,可以防止这种情况,确保线程安全。虽然同步会带来性能影响,但它是构建并发应用的重要工具,平衡同步与性能是使用时需考虑的。了解并恰当使用`synchronized`,能有效应对多线程挑战。
20 1
|
5月前
|
存储 并行计算 监控
为师妹写的《Java并发编程之线程池十八问》被表扬啦!
【6月更文挑战第5天】为师妹写的《Java并发编程之线程池十八问》被表扬啦!
57 7
|
5月前
|
存储 缓存 Java
老程序员分享:Java并发编程:线程池的使用
老程序员分享:Java并发编程:线程池的使用
|
5月前
|
Java
惊呆了!原来JAVA多线程间是这样“窃窃私语”的!
【6月更文挑战第20天】在Java中,多线程通过wait()和notify()/notifyAll()进行通信,确保共享数据的同步。例如,一个生产者线程在队列满时等待,消费者线程在队列空时等待。当条件改变时,一个线程使用notify()唤醒另一个等待的线程,保证数据的一致性。这种“窃窃私语”机制是Java实现线程协作的关键。
41 0
|
5月前
|
Java
当JAVA多线程遇上wait()和notify():一场奇妙的邂逅
【6月更文挑战第20天】JAVA多线程中,wait()和notify()是线程通信的关键。wait()让线程释放锁进入等待,直到被notify()或notifyAll()唤醒。它们用于协调如生产者-消费者问题中的线程协作,确保在同步块内调用,并伴随条件检查以防止虚假唤醒。示例代码展示了一个简单的共享队列,其中生产和消费使用wait/notify实现同步。
36 0
|
6月前
|
监控 安全 Java
CompletableFuture探秘:解锁Java并发编程的新境界
CompletableFuture探秘:解锁Java并发编程的新境界
227 0
|
Java
线程同步经典案例——卖票问题
用上面这种方式创建的所有线程都共享同一份数据,但如果用第一种创建线程的方式,则要将数据用static修饰才能共享
143 0
线程同步经典案例——卖票问题
|
监控 Java
带着面试官畅游Java线程池
java中经常需要用到多线程来处理一些业务,如果单纯使用继承Thread或者实现Runnable接口的方式来创建线程,那样势必有创建及销毁线程耗费资源、线程上下文切换问题。同时创建过多的线程也可能引发资源耗尽的风险,这个时候引入线程池比较合理,方便线程任务的管理。
带着面试官畅游Java线程池
|
算法 Java 程序员
5千字详细讲解java并发编程的AQS
本文讲解AQS的组成,实现原理,应用,源码解析
5千字详细讲解java并发编程的AQS
CyclicBarrier:人齐了,老司机就发车了!(3)
CyclicBarrier:人齐了,老司机就发车了!(3)
126 0
CyclicBarrier:人齐了,老司机就发车了!(3)