Semaphore(信号量)是用来控制访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
Semaphore可以用于做流量控制,特别是共用资源的应用场景。
public static void main(String[] args) { Semaphore semaphore = new Semaphore(10); ExecutorService exec = Executors.newFixedThreadPool(30); for (int i=0;i<30;i++){ exec.execute(new Runnable() { @Override public void run() { try { semaphore.acquire(); System.out.println("我在执行"); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } } }); } exec.shutdown(); }
在上面代码中,虽然有三十个线程在执行,但是只允许10个并发执行。Semaphore的构造方法Semaphore接收一个整形的数字,表示可用的许可证数量。每当调用一次acquire方法就可以获取一个许可证,使用完使用release方法归还许可证。
使用方法介绍
acquire方法
acquire方法是获取一个许可证。当没有许可证可获取时,线程等待。
release方法
release方法是用来归还一个许可证,要注意的是,Semphore传入的参数并不是一直不变的,它是一个动态,在你多次调用release方法,它的值会增加。如果我们在上面代码调用release三次。再打印许可证数量
public static void main(String[] args) throws InterruptedException { Semaphore semaphore = new Semaphore(10); ExecutorService exec = Executors.newFixedThreadPool(30); for (int i=0;i<30;i++){ exec.execute(new Runnable() { @Override public void run() { try { semaphore.acquire(); System.out.println("我在执行"); //Thread.sleep(3000); semaphore.release(); semaphore.release(); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } } }); } Thread.sleep(2000); System.out.println("许可证数量为:"+semaphore.availablePermits()); exec.shutdown(); }
可见,许可证数量增加到了70,而不是你所传入的10了。
intavailablePermits方法
这个方法返回此信号量中当前可用的许可证数
getQueueLength方法
返回正在等待获取许可证的线程数
总结
1、Semphore可以控制并发的线程数
2、Semphore中的许可证数是动态的,每当调用一次release方法,许可证数加1
3、当Semphore构造时传入1时,他可以当做互斥锁使用,等于1表示可获取,等于0表示要等待。