JUC三大辅助类

java.util.concurrent包为我们提供了三大辅助类,帮助我们在某些场景下快速编写并发代码。

  1. CountDownLatch

CountDownLatch(int count)
Constructs a CountDownLatch initialized with the given count.
构造一个用给定计数初始化的CountDownLatch。

CountDownLatch类可以设置一个计数器,然后通过countDown方法来进行减一的操作,使用await方法等待计数器不大于0,然后继续执行await方法之后的语句。
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞。其他线程调用countDown方法会将计数器减一(调用countDown方法的线程不会阻塞)。
当计数器的值变为0时,因await方法而阻塞的线程会被唤醒,继续执行。

案例演示:

import java.util.concurrent.CountDownLatch;

// 演示CountDownLatch
public class CountDownLatchDemo {
    // 6个同学陆续离开教室后,班长锁门
    public static void main(String[] args) throws InterruptedException {
        // 创建CountDownLatch对象,设置初始值
        CountDownLatch countDownLatch = new CountDownLatch(6);
        // 6个同学陆续离开教室
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "号同学离开了教室");
                // 计数-1
                countDownLatch.countDown();
            }, String.valueOf(i)).start();
        }
        // 等待
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "班长锁门");
    }
}

执行结果:
执行结果
2. CyclicBarrier

CyclicBarrier(int parties)
Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and does not perform a predefined action when the barrier is tripped.
创建一个新的CyclicBarrier,当给定数量的参与方(线程)在等待它时,它将触发,并且在触发barrier时不执行预定义的操作。
CyclicBarrier(int parties, Runnable barrierAction)
Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and which will execute the given barrier action when the barrier is tripped, performed by the last thread entering the barrier.
创建一个新的CyclicBarrier,当给定数量的参与方(线程)在等待它时,它将被绊倒;当barrier被绊倒时,它将执行给定的barrier动作,由最后一个进入barrier的线程执行。

CyclicBarrier允许一组线程互相等待,直到到达某个公共屏障点。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该barrier在释放等待线程后可以重用,所以称它为循环栅栏。
CyclicBarrier的构造方法第一个参数是目标障碍数,每次执行CyclicBarrier一次障碍数会加一,如果达到了目标障碍数,才会执行cyclicBarrier.await()之后的语句;可以将CyclicBarrier理解为加一操作。

案例演示:

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

// 演示CyclicBarrier
public class CyclicBarrierDemo {
    // 集齐7颗龙珠就可以召唤神龙
    private static final int NUMBER = 7;
    public static void main(String[] args) {
        // 创建CyclicBarrier对象
        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, () -> {
            System.out.println("集齐7颗龙珠就可以召唤神龙");
        });
        // 集齐7颗龙珠的过程
        for (int i = 1; i <= NUMBER ; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "星龙珠");
                // 等待
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }
}

执行结果:
执行结果

  1. Semaphore

Semaphore(int permits)
Creates a Semaphore with the given number of permits and nonfair fairness setting.
使用给定的许可数量和非公平性设置创建一个信号量。
Semaphore(int permits, boolean fair)
Creates a Semaphore with the given number of permits and the given fairness setting.
使用给定的许可数量和公平性设置创建一个信号量。

一个计数信号量,从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire方法,然后再获取该许可。每个acquire方法添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,semaphore只对可用许可的号码进行计数,并采取相应的行动。
Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

案例演示:

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

// 演示Semaphore
public class SemaphoreDemo {
    // 6辆汽车,停3个停车位
    public static void main(String[] args) {
        // 创建Semaphore,设置许可数量
        Semaphore semaphore = new Semaphore(3);
        // 模拟6辆汽车
        for (int i = 1; i <= 6 ; i++) {
            new Thread(() -> {
                try {
                    // 抢占
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " 抢到了车位");
                    // 设置随机停车时间
                    TimeUnit.SECONDS.sleep(new Random().nextInt(5));
                    System.out.println(Thread.currentThread().getName() + " -----离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // 释放
                    semaphore.release();
                }
            }, String.valueOf(i)).start();
        }
    }
}

执行结果:
执行结果

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PandaThug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值