就是要给令牌池,可获取信号量(令牌或者许可)、放入信号量
常用于控制并发的线程数,也可用于池类资源的访问控制
package com.jysemel.java.lock;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
try {
if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(finalI + "-" + Thread.currentThread().getName() + " 获取信号量");
System.out.println(finalI + "-" + Thread.currentThread().getName() + " 正在运行");
Thread.sleep(TimeUnit.SECONDS.toMillis(6));
semaphore.release();
System.out.println(Thread.currentThread().getName() + " 释放信号量");
} else {
System.out.println(finalI + "-" + "未获取 跳过丢弃");
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 获取异常");
}
}).start();
}
}
}
合理设置许可数:根据系统资源和性能要求设置
使用 try-finally 确保释放许可
考虑使用公平模式:如果对公平性有要求
监控队列长度:避免线程长时间等待
考虑使用 tryAcquire 带超时:避免死锁
代码