Semaphore信号量是Java一个并发工具类
概述
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
计数信号量用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。信号量还可以用来实现某种资源池,或者对容器施加边界。
原理
Semaphore的实现原理与阻塞队列相似:
Semaphore管理着一组许可(permit),许可的初始数量可以通过构造函数设定。操作时首先要获取到许可,才能进行操作,操作完成后需要释放许可。如果没有获取许可,则阻塞直到有许可被释放。如果初始化了一个许可为1的Semaphore,那么就相当于一个不可重入的互斥锁(Mutex)。

形象点的解释就是一个厕所里只有三个坑,但是现在有五个人要方便,所以只能进去三个人其他两个人只能在外面排队等待(阻塞)。等到有一个人解决完出来了,就又可以进去一个人了。
方法
下面是部分方法:
public class Semaphore implements java.io.Serializable {//获取许可,如果许可已经满了,则阻塞public void acquire() throws InterruptedException;//获取指定数量的许可public void acquire(int permits) throws InterruptedException;//释放许可public void release();//获取当前可用许可数量public int availablePermits();//仅在调用时可用时,才从此信号量获取许可。public boolean tryAcquire();//如果在给定的等待时间内可用,并且当前线程尚未中断,则从此信号量获取许可。public boolean tryAcquire(long timeout, TimeUnit unit)throws InterruptedException;//仅在调用时所有可用的条件下,从此信号量获取给定数量的许可。public boolean tryAcquire(int permits);//如果所有信号在给定的等待时间内可用,并且当前线程未中断,则从该信号量获取给定数量的许可。public boolean tryAcquire(int permits, long timeout, TimeUnit unit)throws InterruptedException}
实例
下面是一个简单的信号量使用实例:
public void semaphore(){//线程池ExecutorService executorService = Executors.newCachedThreadPool();//信号量,最多5个线程同时访问final Semaphore semaphore = new Semaphore(5);//模拟10个客户端访问for(int i = 0; i < 10; i++){Runnable runnable = new Runnable() {@Overridepublic void run() {try{//请求许可semaphore.acquire();Thread.sleep(5000);//访问完后,释放semaphore.release();System.out.println(semaphore.availablePermits());}catch (InterruptedException e){e.printStackTrace();}}};//执行任务executorService.execute(runnable);}//关闭线程池executorService.shutdown();}
