(3)breakBarrier() 方法:
private void breakBarrier() { generation.broken = true;//栅栏被打破 count = parties;//重置count trip.signalAll();//唤醒之前阻塞的线程 }
(4)nextGeneration() 方法:
private void nextGeneration() { //唤醒所以的线程 trip.signalAll(); //重置计数器 count = parties; //重新开始 generation = new Generation(); }
(5)reset()方法:
// 重置barrier到初始状态,所有还在等待中的线程最终会抛出BrokenBarrierException。 public void reset() { final ReentrantLock lock = this.lock; lock.lock(); try { breakBarrier(); // break the current generation nextGeneration(); // start a new generation } finally { lock.unlock(); } }
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
三、Semaphore:
1、什么是 Semaphore:
Semaphore
信号量,主要用于控制并发访问共享资源的线程数量,底层基于 AQS 共享模式,并依赖 AQS 的变量 state 作为许可证 permit,通过控制许可证的数量,来保证线程之间的配合。线程使用 acquire()
获取访问许可,只有拿到 “许可证” 后才能继续运行,当 Semaphore
的 permit 不为 0 的时候,对请求资源的线程放行,同时 permit 的值减1,当 permit 的值为 0 时,那么请求资源的线程会被阻塞直到其他线程释放访问许可,当线程对共享资源操作完成后,使用 release()
归还访问许可。
不同于 CyclicBarrier
和 ReentrantLock
,Semaphore
不会使用到 AQS 的 Condition
条件队列,都是在 CLH 同步队列中操作,只是当前线程会被 park。另外 Semaphore
是不可重入的。
2、Semaphore 的公平和非公平两种模式:
Semaphore
通过自定义两种不同的同步器(FairSync 和 NonfairSync)提供了公平和非公平两种工作模式,两种模式下分别提供了限时/不限时、响应中断/不响应中断的获取资源的方法(限时获取总是及时响应中断的),而所有的释放资源的 release()
操作是统一的。
- 公平模式: 遵循 FIFO,调用
acquire()
方法获取许可证的顺序时,先判断同步队列中是不是存在其他的等待线程,如果存在就将请求线程封装成 Node 结点加入同步队列,从而保证每个线程获取同步状态都是按照先到先得的顺序执行的,否则对 state 值进行减操作并返回剩下的信号量 - 非公平模式: 是抢占式的,通过竞争的方式获取,不管同步队列中是否存在等待线程,有可能一个新的获取线程恰好在一个许可证释放时得到了这个许可证,而前面还有等待的线程。
框架流程图如下:
3、尝试获取资源 acquire()方法的执行流程图: