2022-09-25并发编程系列00

CyclicBarrier

基本介绍

循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置『计数个数』,每个线程执行到某个需要“同步”的时刻调用 await() 方法进行等待,当等待的线程数满足『计数个数』时,继续执行

功能和 countdownlatch 一样, 但是 CyclicBarrier 可以循环使用

基本使用

CountdownLatch实现

private static void test01() {
        ExecutorService service = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 5; i++) {
            CountDownLatch latch = new CountDownLatch(2);
            service.submit(() -> {
                log.debug("start ... ");
                latch.countDown();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                log.debug("end ... ");
            });
            service.submit(() -> {
                log.debug("start ... ");
                latch.countDown();
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                log.debug("end ... ");
            });
            service.submit(() -> {
                log.debug("sum start ... ");
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                log.debug("sum end ... ");
            });
        }

        service.shutdown();
    }

可以看到上面的代码我们在每次循环的时候 , 都需要创建 CountDownLatch latch = new CountDownLatch(2);

2022-09-25并发编程系列00

CountdownLatch

基本介绍

基本概念

  • CountDownLatch允许一个或者多个线程去等待其他线程完成操作。

  • CountDownLatch接收一个int型参数,表示要等待的工作线程的个数。

  • 也不一定是多线程,在单线程中可以用这个int型参数表示多个操作步骤。

常用方法

image-20220924101918880

CountDownLatch 用来进行线程同步协作,等待所有线程完成倒计时。

其中构造参数用来初始化等待计数值,await() 用来等待计数归零,countDown() 用来让计数减一

2022-09-25并发编程系列00

AQS

参考文档

AQS简介

AbstractQueuedSynchronizer

  • AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLockSemaphore,其他的诸如ReentrantReadWriteLockSynchronousQueueFutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的同步器。

AQS 核心思想

AQS核心思想是:

  • 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。
  • 如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中

CLH(Craig,Landin,and Hagersten)队列是一个虚拟的双向队列(虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系)。AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点(Node)来实现锁的分配。