服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java多线程同步工具类CyclicBarrier的使用

Java多线程同步工具类CyclicBarrier的使用

2023-04-28 18:23juer Java教程

本文主要介绍了Java多线程同步工具类CyclicBarrier的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

CyclicBarrier是什么

CyclicBarrier是Java并发包中提供的一种同步工具类,它可以让多个线程在某个屏障处等待,直到所有线程都到达该屏障处才继续执行。CyclicBarrier的实现原理是基于ReentrantLock和Condition实现的,通过多次调用await()方法来实现线程的等待和唤醒。

CyclicBarrier的基本使用方法

CyclicBarrier的基本使用方法非常简单,只需要创建一个CyclicBarrier对象,并将计数器的值设置为等待的线程数。每个线程执行完毕后,调用CyclicBarrier的await()方法等待其他线程执行完毕,当所有线程都到达屏障处时,屏障将被打开,所有线程将继续执行。

CyclicBarrier的源码实现

CyclicBarrier的实现原理是基于ReentrantLock和Condition实现的,通过多次调用await()方法来实现线程的等待和唤醒。CyclicBarrier的源码实现主要包括两部分:屏障的初始化和屏障的等待和唤醒。

(1)CyclicBarrier的初始化

在创建CyclicBarrier对象时,需要指定等待的线程数和屏障的执行操作。CyclicBarrier对象的构造方法如下:

?
1
public CyclicBarrier(int parties, Runnable barrierAction)

其中,parties表示等待的线程数,barrierAction表示屏障执行的操作。

在构造方法中,会根据等待的线程数创建一个parties大小的ReentrantLock数组和一个Condition对象。ReentrantLock数组用来保证多个线程能够同时到达屏障处并等待,Condition对象用来进行线程的等待和唤醒。

(2)CyclicBarrier的等待和唤醒

当线程执行到await()方法时,会首先尝试获取ReentrantLock对象的锁,如果获取失败,线程会被加入到等待队列中等待锁的释放。当获取到锁后,线程会判断当前的计数器是否已经达到等待的线程数,如果是,则执行屏障的操作并将计数器重置为parties,唤醒等待队列中的所有线程。如果计数器未达到等待的线程数,则线程会被加入到等待队列中等待其他线程的到来。

CyclicBarrier的await()方法源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public int await() throws InterruptedException, BrokenBarrierException {
    try {
        // 获取锁
        lock.lock();
        // 计数器减1
        int index = --count;
        if (index == 0) {
            // 如果计数器为0,执行屏障操作并唤醒等待队列中的所有线程
            final Runnable command = barrierCommand;
            if (command != null) {
                command.run();
            }
            next
        trip.signalAll();
    } else {
        try {
            // 等待其他线程到达屏障处
            int phase = generation;
            trip.await();
            // 如果是最后一个到达屏障的线程,执行屏障操作并唤醒等待队列中的所有线程
            if (phase == generation) {
                command = barrierCommand;
                if (command != null) {
                    command.run();
                }
            }
            // 计数器重置
            nextGeneration();
        } catch (InterruptedException ie) {
            // 如果线程在等待时被中断,抛出InterruptedException异常
            cancel();
            throw ie;
        } catch (BrokenBarrierException bbe) {
            // 如果屏障被破坏,抛出BrokenBarrierException异常
            broken = true;
            trip = new Condition[parties];
            throw bbe;
        }
    }
    return index;
} finally {
    // 释放锁
    lock.unlock();
}
}

在CyclicBarrier的await()方法中,首先获取ReentrantLock对象的锁,并将计数器减1。如果计数器为0,则执行屏障的操作并唤醒等待队列中的所有线程,如果计数器不为0,则等待其他线程到达屏障处。

在等待过程中,如果线程被中断,将抛出InterruptedException异常。如果屏障被破坏,将抛出BrokenBarrierException异常。如果是最后一个到达屏障的线程,将执行屏障的操作并唤醒等待队列中的所有线程,并将计数器重置为parties。

CyclicBarrier的使用场景

CyclicBarrier适用于多个线程需要等待彼此到达某个屏障点后再继续执行的场景。例如,多个线程需要同时执行某个任务,但某个任务需要等待其他任务完成后才能继续执行,这时就可以使用CyclicBarrier来实现线程的同步和协作。

另外,CyclicBarrier也可以用来实现流水线式的处理,例如生产者消费者模式中,多个生产者可以同时向队列中添加数据,当队列满时,所有生产者需要等待消费者处理完数据后再继续添加数据。

总结

CyclicBarrier是Java并发包中提供的一种同步工具类,可以让多个线程在某个屏障处等待,直到所有线程都到达该屏障处才继续执行。CyclicBarrier的实现原理是基于ReentrantLock和Condition实现的,通过多次调用await()方法来实现线程的等待和唤醒。CyclicBarrier适用于多个线程需要等待彼此到达某个屏障点后再继续执行的场景。

到此这篇关于Java多线程同步工具类CyclicBarrier的使用的文章就介绍到这了,更多相关Java CyclicBarrier内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/7226448512627589157

延伸 · 阅读

精彩推荐
  • Java教程SpringSecurity学习之自定义过滤器的实现代码

    SpringSecurity学习之自定义过滤器的实现代码

    这篇文章主要介绍了SpringSecurity学习之自定义过滤器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    聂晨4132021-07-12
  • Java教程Java中List集合的常用方法详解

    Java中List集合的常用方法详解

    本篇文章给大家带来的内容是关于Java中List集合的常用方法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。下面我们就来学习...

    xiaostudy8682022-03-11
  • Java教程Java中isAssignableFrom的用法详解

    Java中isAssignableFrom的用法详解

    下面小编就为大家带来一篇Java中isAssignableFrom的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    java教程网4512020-07-27
  • Java教程Java中利用Alibaba开源技术EasyExcel来操作Excel表的示例代码

    Java中利用Alibaba开源技术EasyExcel来操作Excel表的示例代码

    这篇文章主要介绍了Java中利用Alibaba开源技术EasyExcel来操作Excel表的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,...

    不会编程的派大星8722021-08-25
  • Java教程通过Java视角简单谈谈局部性原理

    通过Java视角简单谈谈局部性原理

    程序的局部性原理是指程序在执行时呈现出局部性规律,即在一段时间内,整个程序的执行仅限于程序中的某一部分,这篇文章主要给大家介绍了关于通过Jav...

    幻_4432021-10-07
  • Java教程Flink入门级应用域名处理示例

    Flink入门级应用域名处理示例

    这篇文章主要介绍了一个比较简单的入门级Flink应用,代码很容易写,主要用到的算子有FlatMap、KeyBy、Reduce,有需要的朋友可以借鉴参考下,希望能够有所...

    andandan11882022-10-13
  • Java教程Spring oxm入门实例

    Spring oxm入门实例

    这篇文章主要介绍了Spring oxm入门实例,具有一定借鉴价值,需要的朋友可以参考下...

    韧心8162021-03-12
  • Java教程Java Maven构建工具中mvnd和Gradle谁更快

    Java Maven构建工具中mvnd和Gradle谁更快

    这篇文章主要介绍了Java Maven构建工具中mvnd和Gradle谁更快,mvnd 是 Maven Daemon 的缩写 ,翻译成中文就是 Maven 守护进程,下文更多相关资料,需要的小伙伴可...

    Java中文社群9002022-12-06