Semaphore
- Semaphore是一种在多线程中的信号量,主要协调各个线程,以保证它们能够正确、合理的使用公共资源,在操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。相当于给线程规定一个量从而控制允许活动的线程数,可以理解为与数据库连接池一样的,最多允许多少个线程拿到锁资源,其余的就等待锁资源的释放。也可以理解为控制同时访问某个特定资源的线程数量,用在流量控制。
Semaphore的主要方法:
- Semaphore(int permits):创建具有给定许可数的计数信号量并设置为非公平信号量。
- Semaphore(int permits,boolean fair):当fair等于true时,创建具有给定许可数并设置为公平的信号量。
- void acquire(): 从信号量获取一个许可,没有获取到线程将一直阻塞。
- void acquire(int n): 从信号量获取给定数目许可,没有获取到给定的许可,线程将一直阻塞。
- void release(): 释放一个许可,将其返回给信号量。
- void release(int n): 释放n个许可。
- int availablePermits():当前可用的许可数。
- tryAcquire():尝试获取一个锁,成功返回TRUE失败返回false。
- tryAcquire(2,TimeUnit.SECONDS):在定义的时间内一直尝试获取许可,第一个参数是等待的时间,第二个是等待时间的单位。
实例
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Semaphore semaphore = new Semaphore(5);//资源最多可被5个线程并发访问
for(int i = 0;i < 20;i++){
final int threadnum = i;
executorService.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println("start current thread"+Thread.currentThread().getName());
semaphore.acquire();//获取许可
test(threadnum);
semaphore.release();//释放许可
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
executorService.shutdown();//shutdown线程结束
}
private static void test(int threadNum) throws Exception {
System.out.println(" runing "+Thread.currentThread().getName());
Thread.sleep(1000);
}
想知道更多Semaphore的实现原理可以参考源码以及AQS实现它的方法。