携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情 >>
前言
本文将介绍三大多线程工具类Semaphore, CyclicBarrier,理解其作用,如何使用
Semaphore
简称信号量,目程序的是控制的并发量,控制某一段程序可以有多少的线程数,通过协调各个线程,以保证合理的使用资源,内部维护一个计数器,如果信号量内部计数器大于0,信号量减1,然后允许共享这个资源;否则,如果信号量的计数器等于0,信号量将会把线程置入休眠直至计数器大于0.当信号量使用完时,必须释放。
常用方法说明
acquire()
获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。
acquire(int permits)
获取一个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状态。
acquireUninterruptibly() 获取一个令牌,在获取到令牌之前线程一直处于阻塞状态(忽略中断)。
tryAcquire() 尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。
tryAcquire(long timeout, TimeUnit unit) 尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。
release() 释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。
hasQueuedThreads() 等待队列里是否还存在等待线程。
getQueueLength() 获取等待队列里阻塞的线程数。
drainPermits() 清空令牌把可用令牌数置为0,返回清空令牌的数量。
availablePermits() 返回可用的令牌数量。
CyclicBarrier
摘要
在我们现实生活中经常遇到这么一个场景,团队坐车,车只有在全部人员上车后才能出发,人员就是一个个的线程,车就相当是一道屏障,只有全部人员(线程)上车(到达),车(屏障)才能出发(放行) JUC包下就提供了一个这样的同步工具解决了这个场景,CyclicBarrier就实现了多个线程相互等待,当所有线程到达屏障点才能后续的操作
CyclicBarrier 基于 Condition 来实现的
在CyclicBarrier类的内部有一个计数器,每个线程在到达屏障点的时候都会调用await方法将自己阻塞,此时计数器会减1,当计数器减为0的时候所有因调用await方法而被阻塞的线程将被唤醒。这就是实现一组线程相互等待的原理