前言
大家应该都用过synchronized
关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什么好的办法呢? 答案就是JUC提供的信号量Semaphore
。
介绍和使用
Semaphore
(信号量)可以用来限制能同时访问共享资源的线程上限,它内部维护了一个许可的变量,也就是线程许可的数量Semaphore
的许可数量如果小于0个,就会阻塞获取,直到有线程释放许可Semaphore
是一个非重入锁
API介绍
- 构造方法
public Semaphore(int permits)
:permits
表示许可线程的数量public Semaphore(int permits, boolean fair)
:fair
表示公平性,如果设为true
,表示是公平,那么等待最久的线程先执行
- 常用API
public void acquire()
:表示一个线程获取1个许可,那么线程许可数量相应减少一个public void release()
:表示释放1个许可,那么线程许可数量相应会增加
- 其他API
void acquire(int permits)
:表示一个线程获取n个许可,这个数量由参数permits
决定void release(int permits)
:表示一个线程释放n个许可,这个数量由参数permits
决定int availablePermits()
:返回当前信号量线程许可数量int getQueueLength()
: 返回等待获取许可的线程数的预估值
基本使用
public static void main(String[] args) {
// 1. 创建 semaphore 对象
Semaphore semaphore = new Semaphore(2);
// 2. 10个线程同时运行
for (int i = 0; i < 8; i++) {
new Thread(() -> {
// 3. 获取许可
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
log.debug("running...")