Semaphore是JUC==java.util.concurrent包提供的一个共享锁,一般称之为信号量。本质上是一个共享锁。维持一定数量的许可,当线程通过acquire请求许可时,若已超过指定数量,则必须等待。
Semaphore通过自定义的同步器维护了一个或多个共享资源,线程通过调用acquire获取共享资源,通过调用release释放。
两个构造方法
构造方法一中,没有指定是公平锁还是非公平锁,所以Semaphore默认是非公平锁,但是也可以指定为公平锁。
Semaphore 类中比较重要的几个方法:
- acquire(): 用来获取一个许可,若无许可能够获得,则会一直等待,直到获
得许可 - acquire(int permits):获取 permits 个许可
- release() :释放许可。注意,在释放许可之前,必须先获获得许可
- release(int permits) :释放 permits 个许可
上面 4 个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法
- tryAcquire():尝试获取一个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false
- tryAcquire(long timeout, TimeUnit unit):尝试获取一个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false
- tryAcquire(int permits):尝试获取 permits 个许可,若获取成功,则立即返回 true,若获取失败,则立即返回 false
- tryAcquire(int permits, long timeout, TimeUnit unit): 尝试获取 permits个许可,若在指定的时间内获取成功,则立即返回 true,否则则立即返回 false
还可以通过 availablePermits()方法得到可用的许可数目。
nonfaieTryAcquireShared()方法:
每有1次acquire方法调用,就调用一次该方法,将标志位减去请求许可数。若remaining小于0,则返回负值,从而线程等待
tryReleaseShared()方法:
每有一次调用release方法,就调用一次该方法。将标识位加上所要释放的许可数。
使用场景
实例一:咱们公司男厕所只有三个坑,也就是同一时间是只能有三个人上大号,其他人能只能
等待,任何时候上大号的人永远小于等于3人,
实例二:假设咱们停车场只有10个车位。那么要是同时来了20个车,保安人员只能让10辆车进
,其他排队等候。任何时候停车场所停车辆数永远小于等于10
java代码实现:
例子不是很雅观望谅解
可以看得出,第一、第二、第三同时开始上厕所。当第一上完后,蹲坑就空出一个来了,所以第四开始上厕所,第四上完,第五开始上厕所。可以看出上厕所人数永远不会超过三个。如果把排队上厕所人数设置大更多