Semaphore简介
Semaphore 一般译作 信号量
,它也是一种线程同步工具,主要用于多个线程对共享资源进行并行操作的一种工具类。它代表了一种许可
的概念,是否允许多线程对同一资源进行操作的许可,使用 Semaphore 可以控制并发访问资源的线程个数。
使用场景
Semaphore 的使用场景主要用于流量控制
,比如数据库连接,同时使用的数据库连接会有数量限制,数据库连接不能超过一定的数量,当连接到达了限制数量后,后面的线程只能排队等前面的线程释放数据库连接后才能获得数据库连接。
再比如交通公路上的红绿灯,绿灯亮起时只能让 100 辆车通过,红灯亮起不允许车辆通过。
再比如停车场的场景中,一个停车场有有限数量的车位,同时能够容纳多少台车,车位满了之后只有等里面的车离开停车场外面的车才可以进入。
代码实现
下面我们就来模拟一下停车场的业务场景:在进入停车场之前会有一个提示牌,上面显示着停车位还有多少,当车位为 0 时,不能进入停车场,当车位不为 0 时,才会允许车辆进入停车场。所以停车场有几个关键因素:停车场车位的总容量,当一辆车进入时,停车场车位的总容量 - 1,当一辆车离开时,总容量 + 1,停车场车位不足时,车辆只能在停车场外等待。
/** * @desc: 信号量的使用 * @author: Mr_YanMingXin * @create: 2021/7/27-9:36 **/ public class Test01 { private static Semaphore semaphore = new Semaphore(10); public static void main(String[] args) { ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(15, 100, 1000, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 0; i < 100; i++) { poolExecutor.execute(() -> { // 判断是否允许停车 if (semaphore.availablePermits() == 0) { System.out.println("停车位不足,请耐心等待"); } try { //获取 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " 进入停车场 <----"); //车辆停留时间 Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " 驶出停车场 ---->"); //释放 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }); } poolExecutor.shutdown(); } }
在上面这段代码中,我们给出了 Semaphore 的初始容量,也就是只有 10 个车位,我们用这 10 个车位来控制 100 辆车的流量,所以结果和我们预想的很相似,即大部分车都在等待状态。但是同时仍允许一些车驶入停车场,驶入停车场的车辆,就会 semaphore.acquire 占用一个车位,驶出停车场时,就会 semaphore.release 让出一个车位,让后面的车再次驶入。
部分内容来自:[https://github.com/crisxuan/bestJavaer/blob/master/java-concurrent/java-semaphore.md]