信号量Semaphore详解以及应用
介绍
参考: https://blog.csdn.net/qq_19431333/article/details/70212663
Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有实际的许可证这个对象,Semaphore只是维持了一个可获得许可证的数量。Semaphore经常用于限制获取某种资源的线程数量。
基本用法
package com.person; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * Semaphore是信号量,用于管理一组资源。 * 其内部是基于AQS的共享模式,AQS的状态表示许可证的数量。 * 在许可证数量不够时,线程将会被挂起; * 而一旦有一个线程释放一个资源,那么就有可能重新唤醒等待队列中的线程继续执行。 */ public class SemaphoreTest { public static void main(String[] args) throws Exception{ /** * 两种构造方法 * 都必须提供许可的数量,第二个构造方法可以指定是公平模式还是非公平模式,默认非公平模式。 * 1.new Semaphore(5); 非公平模式,即抢占模式。 * new Semaphore(5,false); 非公平模式,即抢占模式。 * 2.new Semaphore(5,true); 公平模式。 * * FairSync公平模式与NonFairSync不公平模式的区别: * 就在于会首先判断当前队列中有没有线程在等待,如果有,就老老实实进入到等待队列; * 而不像NonfairSync一样首先试一把,说不定就恰好获得了一个许可,这样就可以插队了 */ //抢占模式 //Semaphore semaphore = new Semaphore(5); //公平模式,公平模式在获得许可时会先查看下是否有线程在等待,如果有则直接阻塞等待 Semaphore semaphore = new Semaphore(5,true); //是否公平模式 true-公平模式 false-抢占模式 boolean isFair = semaphore.isFair(); System.out.println(isFair);//true //获得一个许可,如果得不到则会一直阻塞 semaphore.acquire(); //获得可用的许可数量 int available = semaphore.availablePermits(); System.out.println(available); //4 //添加一个许可,从而可能释放一个正在阻塞的获取者 semaphore.release(); available = semaphore.availablePermits(); System.out.println(available); //5 //***获得许可,并设置最大的阻塞时间,成功获得许可返回true,超过设置的最大时间还未获得许可则返回false boolean isAcquire = semaphore.tryAcquire(4, TimeUnit.SECONDS); System.out.println(isAcquire); //true //一次将剩余的许可数量全部取走,返回剩下所有的许可数 int drain = semaphore.drainPermits(); System.out.println(drain); //4 } }
应用场景
1.主要应用在多线程的环境中,由Semaphore限制获取有限的线程资源。
应用实例
详见另一篇博文: https://www.cnblogs.com/walixiansheng/p/9561911.html