JUC辅助类

详情链接
https://www.taodudu.cc/news/show-60458.html

前言

JUC中提供了三种常用的辅助类,通过这些辅助类可以很好的解决线程数量过多时Lock锁的频繁操作。这三种辅助类为:

  1. CountDownLatch
  2. CyclicBarrier
  3. Semaphore

1.CountDownLatch

下图是Jdk1.8中解释的CountDownLatch类功能,简单而言,在实例化时,需要传入一个信号量,每当一个线程执行后,信号量减1,当信号量为0时,释放阻塞的线程。

在这里插入图片描述

用个小Demo模拟,需求是启动5个线程,当5个线程执行完后,main线程才能继续执行,如果不使用CountDownLatch,线程的调用将不可控。

public static void main(final String[] args) throws InterruptedException {
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 执行");
        }, String.valueOf(i)).start();
    }
    System.out.println(Thread.currentThread().getName() + "最终执行");
}

在这里插入图片描述
可以看出,不使用任何线程控制等方法,线程是随计算机调度的,线程的执行顺序并不是我们预期希望的。

当使用CountDownLatch,实例化时将信号量设置为5,每当一个线程执行后,信号量减1,当5个线程执行完后,信号量为0,main线程才执行。

public static void main(final String[] args) throws InterruptedException {
   //实例化,并传入信号初始量
    CountDownLatch countDownLatch = new CountDownLatch(5);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 执行");
            //信号量减1
            countDownLatch.countDown();
        }, String.valueOf(i)).start();
    }
    countDownLatch.await();
    System.out.println(Thread.currentThread().getName() + "最终执行");
}

在这里插入图片描述

2.CyclicBarrier

下图是Jdk1.8中解释的CyclicBarrier类功能,简单而言,在实例化时,需要传入一个信号量和Runnable接口,每当一个线程执行后,信号量加1,当信号量的值达到传入的预期值,则执行方法。
在这里插入图片描述

这里我们定义了只要达到3个线程,就执行方法。

public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
        System.out.println("---------方法执行---------");
    });

    for (int i = 0; i < 3; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t执行");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }, String.valueOf(i)).start();
    }
}

在这里插入图片描述

3. Semaphore(信号灯)

比如:停车6个车3车位,银行排队10个人3窗口。

下图为Jdk1.8文档中的解释,简单来说,在初始化时设定一个预期值,当线程数量达到预期值,其他线程被阻塞,只有当线程使用完毕,其他线程才能重新开始抢占资源。

在这里插入图片描述

public static void main(String[] args) {
    Semaphore Semaphore = new Semaphore(3);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            try {
                Semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + "\t抢占到资源");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "\t释放了资源");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                Semaphore.release();
            }
        }, String.valueOf(i)).start();
    }
}

从运行结果中很容易理解,我们定义了初始值为3,说明只要有3个线程抢占到资源,直到他们释放,其他资源都只能等待。
在这里插入图片描述

Semaphore是对锁的扩展。无论是内部锁synchronized还是重入锁ReentranLock,一次都只允许一个线程访问一个资源,而信号量却可以指定多个线程,同时访问某一个资源。一定记得release()。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值