述
Semaphore
信号量,也是一个线程协作的工具,可以用来限制或管理数量有限的资源的使用
用法
信号量的作用是维护一个 “许可证” 的计数,线程可以获取许可证,然后信号量剩余许可证数量减一,当信号量所拥有的许可证为0的时候,下一个想要获取许可证的线程就需要等待,直到有另外的线程释放了许可证
常用的几个方法如下
- 构造函数: 和上文的
CountDownLatch
一样,Semaphore
在初始化的时候也需要指定许可证的数量,还有一个构造参数是配置公平策略,如果是 true ,当有了新的许可证的时候,会把它给等待时间最长的线程 acquire()
/acquireUninterruptibly()
: 这两个方法是用来获取许可证的,从名字上来看就知道,后面的是可以在获取的过程种被打断的tryAcquire(timeout)
/tryAcquire()
: 这两个方法是尝试获取许可证,在规定时间内立即返回,不会阻塞release()
: 释放许可证
使用案例
用个具体的代码演示以下信号量的使用
1 | @Slf4j |
新建一个3个许可证的信号量,然后新建 100 个线程都去获取证书,执行后再释放掉,看一下控制台输出
1 | 11:03:17.556 [Thread-1] INFO com.learning.java.cooperation.SemaphoreTest$Task - 获取到了许可证,执行具体逻辑... |
可以看到每次执行的都是3个线程,释放之后才会有下一批线程获取到,这里上面构造函数中没有设置为公平的,所以这里获取到许可证的线程并不是按顺序的
注意点
acquire()
和release()
方法都有一个重载的方法,可以传入一个 int 类型的参数,表示获取/释放几个许可证,但是并不强制获取几个就得释放几个,比如获取两个释放一个也是可以的,但最后许可证会越来越少,会导致程序卡死- 初始化的时候一般设置为公平的,更加合理
- 并不是必须由获取许可证的线程释放许可证, 比如A线程获取了许可证,可以由B线程释放