semaphore信号量使用以及原理

什么是信号量(semaphore)

  • 是一种JDK内置同步器,通过他可以实现多线程对公共资源的并发访问请求
  • 可以看成一个计数器,当计数器的值小于许可最大值时,所有acquire方法线程都可以得到一颗许可继续执行,而调用release方法则可以让计数器的值减一

常用的重要方法

1public Semaphore(int permits)
   // 创建一个给定许可数量的信号量对象,且默认以非公平锁方式获取资源

2public Semaphore(int permits, boolean fair)
   // 创建一个给定许可数量的信号量对象,且是否公平方式由传入的fair布尔参数值决定

3public void acquire() 
   // 从此信号量获取一个许可,当许可数量小于零时,则阻塞等待
   
4public void acquire(int permits)  
   // 从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话则会抛InterruptedException异常
   
5public void acquireUninterruptibly(int permits)   
   // 从此信号量获取permits个许可,当许可数量小于零时,则阻塞等待,但是当阻塞等待的线程被唤醒后发现被中断过的话不会抛InterruptedException异常
   
6public void release()
   // 释放一个许可

7public void acquire(int permits)
   // 释放permits个许可

实现原理

在这里插入图片描述

  • semaphore类的实现是基于AQS同步器来实现的,不管是公平还是非公平都是基于AQS的共享模式,只是在操作逻辑有差异。
    在这里插入图片描述
    在这里插入图片描述
  • 内部子类Syn是公平模式FairSync和非公平模式NonfairSync类的抽象父类
  • 其中提供两个构造函数,两个参数为许可最大数和是否使用公平模式。

非公平模式实现

在这里插入图片描述
在这里插入图片描述

  • 提供了非公平模式信号量获取的方法nonfairTryAcquireShared
    • 在许可数量允许的情况下(remaining<0),可以让所有线程进行自旋操作(CAS)
    • 当剩余信号量小于0时则返回负数(return remaining),导致线程进入等待队列(AQS)
  • tryReleaseShared方法则提供释放信号量操作
    • 通过自旋操作CAS将信号量增加到当前剩余许可数上

公平模式的实现

在这里插入图片描述

  • 公平模式和非公平模式最主要差异是在获取信号量时的机制
  • 不同的地方就在方框的两行代码,它会检查是否已经存在等待队列,如果有就直接(return -1)让AQS同步器将当前线程进入等待队列

例子

在这里插入图片描述
在这里插入图片描述

发布了20 篇原创文章 · 获赞 0 · 访问量 255

猜你喜欢

转载自blog.csdn.net/white_zzZ/article/details/103954859
今日推荐