介绍

Semaphore是什么

Semaphore可以称为信号量,这个原本是操作系统中的概念,是一种线程同步方法,配合PV操作实现线程之间的同步功能。信号量可以表示操作系统中某种资源的个数,因此可以用来控制同时访问该资源的最大线程数,以保证资源的合理使用

Java的JUC对Semaphore做了具体的实现,其功能和操作系统中的信号量基本一致,也是一种线程同步并发工具

使用场景

Semaphore常用于某些有限资源的并发使用场景,即限流

场景一
数据库连接池对于同时连接的线程数有限制,当连接数达到限制后,接下来的线程必须等待前面的线程释放连接才可以获得数据库连接

场景二
医院叫号,放出的号数是固定的,不然医院窗口来不及处理。因此只有取到号才能去门诊,没取到号的只能在外面等待放号

Semaphore常用方法介绍

构造函数

  • Semaphore(int permits):创建一个许可数为permitsSemaphore
  • Semaphore(int permits, boolean fair):创建一个许可数为permitsSemaphore,可以选择公平模式或非公平模式

获取许可

  • void acquire() throws InterruptedException:获取一个许可,响应中断,获取不到则阻塞等待
  • void acquire(int permits) throws InterruptedException:获取指定数量的许可,响应中断,获取不到则阻塞等待
  • void acquireUninterruptibly():获取一个许可,忽略中断,获取不到则阻塞等待
  • void acquireUninterruptibly(int permits):获取指定数量的许可,忽略中断,获取不到则阻塞等待
  • int drainPermits():获取当前所有可用的许可,并返回获得的许可数

释放许可

  • void release():释放一个许可
  • void release(int permits):释放指定数量的许可

尝试获取许可

  • boolean tryAcquire():尝试获取一个许可,如果获取失败不会被阻塞,而是返回false。成功则返回true
  • boolean tryAcquire(int permits):尝试获取指定数量的许可,如果获取失败不会被阻塞,而是返回false。成功则返回true
  • boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException:尝试获取一个许可,如果获取失败则会等待指定时间,如果超时还未获得,则返回false。获取成功则返回true。在等待过程中如果被中断,则会立即抛出中断异常
  • boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException:尝试获取指定数量的许可,如果获取失败则会等待指定时间,如果超时还未获得,则返回false。获取成功则返回true。在等待过程中如果被中断,则会立即抛出中断异常

其他方法

  • boolean isFair():判断信号量是否是公平模式
  • int availablePermits():返回当前可用的许可数
  • boolean hasQueuedThreads():判断是否有线程正在等待获取许可
  • int getQueueLength():返回当前等待获取许可的线程的估计值。该值并不是一个确定值,因为在执行该函数时,线程数可能已经发生了变化

Semaphore使用示例

针对“使用场景”的场景二,假设医院最多接待2个人,如果接待满了,那么所有人都必须在大厅等待(不能“忙等”

代码如下:

无论如何,医院内最多有5个病人同时接诊。这也说明了Semaphore可以控制某种资源最多同时被指定数量的线程使用

作者:酒冽        出处:https://www.cnblogs.com/frankiedyz/p/15674098.html
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
12-24 16:08