背景介绍

等待指定数量的线程完成任务的并发组件。例如:下面代码中,提交10个线程执行,每次最多3个线程并发执行,其他线程需要等待。常用于限流等场景

  1. public class SemaphoreTest {
  2. @Test
  3. public void testSemaphore() throws InterruptedException {
  4. Semaphore semaphore = new Semaphore(3);
  5. for (int i = 0; i < 10; i++) {
  6. new Thread(() -> {
  7. try {
  8. semaphore.acquire();
  9. Thread.sleep(1000);
  10. System.out.println("线程执行");
  11. semaphore.release();
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }).start();
  16. }
  17. // 仅仅让当前线程阻塞,方便控制台看返回结果
  18. Thread.currentThread().join();
  19. }
  20. }

核心原理

核心变量分析

Semaphore底层是通过AQS进行并发控制的

截屏2021-01-20 下午11.13.56.png

初始化

当我们调用构造方法时就是设置AQS中的state值

Semaphore semaphore = new Semaphore(3);

acquire方法

acquire方法通过对aqs的state进行减1,判断其值是否大于等于0,则通过cas的方式对state值减1,如果cas失败则自旋。如果该值小于0则当前线程进入等待队列
截屏2021-01-20 下午11.39.35.png

release方法

release方法就是不断通过cas方式对state值加1,如果成功则释放锁并唤醒队首线程,如果失败则继续通过cas尝试对state值加1
截屏2021-01-20 下午11.47.27.png