一、什么是Semaphore
Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的事情后释放许可信号,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:
availablePermits函数用来获取当前可用的资源数量
wc.acquire(); //申请资源
wc.release();// 释放资源
// 创建一个计数阈值为5的信号量对象
// 只能5个线程同时访问
Semaphore semp = new Semaphore(5);
try {
// 申请许可
semp.acquire();
try {
// 业务逻辑
} catch (Exception e) {
} finally {
// 释放许可
semp.release();
}
} catch (InterruptedException e) {
}
二、Semaphore的使用示例
package com.juc.countdownlatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
private static final int THREAD_COUNT = 10;
private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
// 创建5个许可,允许5个并发执行
private static Semaphore s = new Semaphore(5);
public static void main(String[] args) {
//创建10个线程执行任务
for (int i = 0; i < THREAD_COUNT; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
//同时只能有5个线程并发执行保存数据的任务
s.acquire();
System.out.println("线程" + Thread.currentThread().getName() + " 保存数据");
Thread.sleep(2000);
//5个线程保存完数据,释放1个许可,其他的线程才能获取许可,继续执行保存数据的任务
s.release();
System.out.println("线程" + Thread.currentThread().getName() + " 释放许可");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
executorService.shutdown();
}
}