CyclicBarrier线程同步共享变量底层原理示例解析

2023-08-06 0 1,321

目录

引言

CyclicBarrierJava.util.concurrent包中提供的另一个同步工具类,它允许一组线程在某个共同点处相互等待,并在所有线程都达到某个条件时继续执行。

CyclicBarrier的代码示例

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
    public static void main(String[] args) {
        int workerCount = 3;
        Runnable barrierAction = () -> System.out.println(\"All workers have reached the barrier.\");
        CyclicBarrier cyclicBarrier = new CyclicBarrier(workerCount, barrierAction);
        for (int i = 0; i < workerCount; i++) {
            Thread worker = new Thread(new Worker(cyclicBarrier));
            worker.start();
        }
    }
    static class Worker implements Runnable {
        private final CyclicBarrier cyclicBarrier;
        public Worker(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
        @Override
        public void run() {
            try {
                // 模拟工作任务的执行
                Thread.sleep(2000);
                System.out.println(\"Worker \" + Thread.currentThread().getId() + \" has reached the barrier.\");
                cyclicBarrier.await(); // 工作线程到达屏障,等待其他线程
                System.out.println(\"Worker \" + Thread.currentThread().getId() + \" continues its work.\");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

打印结果:

Worker 13 has reached the barrier.
Worker 14 has reached the barrier.
Worker 12 has reached the barrier.
All workers have reached the barrier.
Worker 14 continues its work.
Worker 13 continues its work.
Worker 12 continues its work.

首先,创建了一个CyclicBarrier对象cyclicBarrier,并指定workerCount为3(代表需要等待的线程数),并设置barrierAction为一个Runnable,用于在所有线程到达屏障时执行。

然后,使用一个for循环创建了3个工作线程(Worker),每个工作线程在完成一部分任务后都会调用await()方法来等待其他线程。在工作线程内部,它们会先模拟一段工作任务的执行,然后调用cyclicBarrier.await()方法等待其他线程。

当所有的工作线程都到达屏障时,即达到指定的workerCount时,它们就会继续执行后续的任务。CyclicBarrier会自动重置计数器,可以继续使用。

在示例中,为了模拟工作任务的执行,工作线程通过Thread.sleep(2000)来暂停2秒钟。然后,每个工作线程输出自己到达屏障的信息,等待其他线程。当所有线程都到达屏障时,会执行设置的barrierAction,即输出所有工作线程都到达了屏障。在此之后,工作线程会继续执行后续的工作任务。

小结

CyclicBarrier可以用于在多个线程中实现同步,当所有线程都到达屏障时,才能继续执行后续的任务。它常用于需要等待所有线程完成一定阶段的任务后再进行下一阶段的场景

使用CyclicBarrier示例 模拟收集龙珠的场景

当收集到7颗龙珠后,会触发一个动作(召唤神龙)。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println(\"召唤神龙\");
        });
        for (int i = 1; i <= 7; i++) {
            final int temp = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + \"\\t 收集到第\" + temp + \"颗龙珠\");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}

在这个示例中,我们创建了一个 CyclicBarrier 对象,指定计数器的值为 7,当 7 个线程都调用了 await() 方法后,会触发传入的 Runnable 对象,即召唤神龙的动作。

在 for 循环中,我们创建了 7 个线程,并分别模拟收集到不同的龙珠。每个线程执行完收集龙珠的操作后,调用 cyclicBarrier.await() 方法,等待其他线程。

当所有线程都调用了 await() 方法后,CyclicBarrier 中的计数器会达到设定的值,触发召唤神龙的动作。输出结果可能类似于以下内容:

1     收集到第1颗龙珠
2     收集到第2颗龙珠
3     收集到第3颗龙珠
4     收集到第4颗龙珠
5     收集到第5颗龙珠
6     收集到第6颗龙珠
7     收集到第7颗龙珠
召唤神龙

这个示例展示了如何使用 CyclicBarrier 来等待多个工作线程执行完毕,并在所有线程完成后触发一个动作。

CyclicBarrier 底层原理

CyclicBarrier 的底层原理涉及到线程同步和共享变量的操作。

CyclicBarrier 的底层原理是基于 AQS(AbstractQueuedSynchronizer)实现的。 CyclicBarrier 内部维护了一个共享的同步状态(state)和一个等待队列。每个线程在调用 await() 方法时,会将线程加入等待队列,并检查当前状态是否为初始状态。如果是初始状态,则线程会进入休眠状态,等待其他线程的到达。当所有线程都调用 await() 方法后,它们会相互唤醒,继续执行后续的任务。同时,CyclicBarrier 的状态会被重置为初始状态,可以继续使用。这样就实现了线程之间的协调与等待的功能。

在 CyclicBarrier 中,有一个计数器(count)和一个屏障点(barrier)用于实现线程的同步。计数器的初始值由构造函数传入,每当一个线程调用 await() 方法时,计数器的值会减一。当计数器的值变为零时,表示所有线程都已到达屏障点,可以继续执行后续操作。

CyclicBarrier 使用了共享变量和内置的线程同步机制来实现等待和通知的功能。具体来说,它使用了以下几个关键的方法和数据结构:

  • await():线程调用 await() 方法时,会尝试获取内置的锁,然后将计数器的值减一。如果计数器的值不为零,那么线程会被阻塞,等待其他线程到达屏障。如果计数器的值变为零,那么所有在屏障上等待的线程将会被唤醒,可以继续执行后续操作。
  • 内置的同步机制:CyclicBarrier 内部使用了内置的同步机制,如锁、条件变量等,来实现线程的等待和通知机制。
  • 循环使用的特性:与 CountDownLatch 不同,CyclicBarrier 是可以循环使用的。当所有线程都到达屏障后,计数器会被重置为初始值,可以进行下一轮的等待和通知。

在底层实现中,CyclicBarrier 使用了类似于 ReentrantLock 和 Condition 的机制来实现线程的等待和唤醒。当一个线程调用 await() 方法时,它会尝试获取内置的锁,然后检查计数器的值。如果计数器的值不为零,线程会通过条件变量进入等待状态。当计数器的值变为零时,最后一个到达屏障的线程会通过条件变量唤醒其他等待的线程,使它们继续执行。

需要注意的是,CyclicBarrier 是可重入的,即同一个线程可以多次调用 await() 方法等待其他线程到达屏障。只有当所有线程都调用了 await() 方法,计数器的值才会变为零,触发屏障的打开。

总结

CyclicBarrier 的底层原理是通过共享变量和内置的线程同步机制来实现线程的等待和通知。它提供了一种循环使用的屏障机制,可以在某个屏障点上同步等待,然后同时继续执行后续的任务。

以上就是CyclicBarrier线程同步共享变量底层原理示例解析的详细内容,更多关于CyclicBarrier线程同步共享变量的资料请关注其它相关文章!

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 CyclicBarrier线程同步共享变量底层原理示例解析 http://www.20zxx.cn/806569/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务