信号量,控制同时访问资源的线程个数。
在线程访问资源前,必须先从信号量中获取许可证(acquire()),当线程使用资源结束后,调用release()方法,会释放一个信号,以便其他的线程可以获取信号量。
共享型
源码分析
acquire()
在信号量池中获取一个信号,在获取许可之前一直阻塞,除非线程被中断
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
release()
释放一个许可,将其返回信号量。
使用场景
比如某个接口限制并发访问的线程数,在单点的情况下,可以使用信号量控制。
private Semaphore semaphore = new Semaphore(2);
private CountDownLatch countDownLatch = new CountDownLatch(3);
public static void main(String[] args){
SemaphoreDemo semaphoreDemo = new SemaphoreDemo();
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
semaphoreDemo.semaphore.acquire();
semaphoreDemo.countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + "正在执行...");
semaphoreDemo.semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"Thread-" + i).start();
}
try {
semaphoreDemo.countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "正在执行...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}