JUC-18. 常用的辅助类

想了解更多JUC的知识——JUC并发编程合集

18. 常用的辅助类

1. 同步工具类

1.1 CountDownLatch

概念
  • CountDownLatch允许一个或者多个线程去等待其他线程完成操作。
  • CountDownLatch接收一个int型参数,表示要等待的工作线程的个数
方法
  • await():使当前线程进入同步队列进行等待,直到 latch 的值被减到0或者当前线程被中断,当前线程就会被唤醒。
  • await(long timeout, TimeUnit unit):带超时时间的await()。
  • countDown():使 latch 的值减1,如果减到了0,则会唤醒所有等待在这个 latch 上的线程。
  • getCount():获得latch的数值。
案例
//模拟放学锁门,只有六个同学全部走了,老师才可以锁门
public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        //总数为6
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "离开了教室");
                countDownLatch.countDown();//计数器-1
            },String.valueOf(i)).start();
        }
        //等待计数器归0再向下执行
        countDownLatch.await();
        System.out.println("关门了!");
    }
}

1.2 CyclicBarrier

概述
  • CyclicBarrier:循环屏障,可以给离散的任务添加逻辑层次。
  • 各个线程会互相等待,直到所有线程都完成了,再一起突破屏障。如上课时,只有所有学生都到了,老师才会上课。
构造器
  • CyclicBarrier有两个构造器

    • CyclicBarrier(int parties) :创建一个CyclicBarrier对象,并指定其parties

    • CyclicBarrier(int parties, Runnable barrierAction) :指定parties,并且执行其callBack(在所有线程都到达时执行此barrierAction)

    • parties:当前CyclicBarrier管理的线程的个数

方法
  • await():等待所有 parties 已经在这个障碍上调用了await。如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一:

    • 最后一个线程到达
    • 其他一些线程中断当前线程
    • 其他一些线程中断了其他等待线程中的一个
    • 其他一些线程在等待屏障时超时
    • 其他一些线程在这个屏障上调用 reset()
  • await(long timeout, TimeUnit unit):等待所有 parties已经在此屏障上调用 await ,或指定的等待时间过去。

  • getNumberWaiting():返回目前正在等待障碍的各方的数量。

  • getParties():返回突破障碍所需的数量

  • isBroken():查询这个障碍是否处于破碎状态。

  • reset():将屏障重置为初始状态。

案例
//模拟考试交卷,只有等到全部人交卷了,才可以走
public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(6,()->{
            System.out.println("考试结束,大家可以走了");
        });

        for (int i = 1; i <= 6; i++) {
            int temp = i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "交卷,老师收了学生" + temp + "的试卷");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },"学生" + i).start();
        }

    }
}

1.3 两者的比较

CountDownLatchCyclicBarrier
软件包java.util.concurrentjava.util.concurrent
适用情景主线程等待多个工作线程结束多个线程之间互相等待,直到所有线程达到一个障碍点(Barrier point)
等待结束各线程之间不再互相影响,可以继续做自己的事情。不再执行下一个目标工作在屏障点达到后,允许所有线程继续执行,达到下一个目标。可以重复使用CyclicBarrier
异常如果其中一个线程由于中断,错误,或超时导致永久离开屏障点,其他线程也将抛出异常。
其他如果BarrierAction不依赖于任何Party中的所有线程,那么在任何party中的一个线程被释放的时候,可以直接运行这个Action。

2. Semaphore

2.1 概念

  • Semaphore通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。
  • 作用:多个共享资源互斥的使用,并发限流,控制最大的线程数

2.2 常用方法

  • acquire():获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。

  • acquire(int permits):获取一个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状

  • acquireUninterruptibly():获取一个令牌,在获取到令牌之前线程一直处于阻塞状态(忽略中断)。

  • tryAcquire():尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。

  • tryAcquire(long timeout, TimeUnit unit):尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。

  • release():释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。

  • hasQueuedThreads():等待队列里是否还存在等待线程。

  • getQueueLength():获取等待队列里阻塞的线程数。

  • drainPermits():清空令牌把可用令牌数置为0,返回清空令牌的数量。

  • availablePermits():返回可用的令牌数量。

2.3 案例

//模拟抢车位,只有三个车位,六辆车
public class SemaphoreTest {
    public static void main(String[] args) {
        //线程数量-三个车位
        Semaphore semaphore = new Semaphore(3);

        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();//acquire()得到,即抢到车位
                    System.out.println(Thread.currentThread().getName() + "抢到车位");
                    TimeUnit.SECONDS.sleep(2);//模拟停车时间为2s
                    System.out.println(Thread.currentThread().getName() + "离开车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();//release()释放,即离开车位
                }
            }).start();
        }
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Daylan Du

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

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

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

打赏作者

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

抵扣说明:

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

余额充值