Semaphore自白:限流器用我就对了!(2)

简介: Semaphore自白:限流器用我就对了!(2)

项目经验


接下来,咱们使用代码的方式来演示 Semaphore 的使用。我们以停车场的限流为例,假设整个停车场只有 2 个车位(车位虽少,但足矣说明问题),但来停车的却有 5 辆车,显然车位不够用了,此时需要保证停车场最多只能有 2 辆车,接下来咱们使用 Semaphore 来实现车辆的限流功能,具体实现代码如下:


import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
 * Author:磊哥
 * By:Java中文社群
 */
publicclass SemaphoreExample {
    // 创建信号量
    static Semaphore semaphore = new Semaphore(2);
    public static void main(String[] args) {
        // 创建 5 个固定的线程数
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        // 定义执行任务
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // 拿到当前线程的名称
                String tname = Thread.currentThread().getName();
                System.out.println(String.format("老司机:%s,停车场外排队,时间:%s",
                        tname, new Date()));
                try {
                    // 执行此行,让所有线程先排队等待进入停车场
                    Thread.sleep(100);
                    // 执行阻塞
                    semaphore.acquire();
                    System.out.println(String.format("老司机:%s,已进入停车场,时间:%s",
                            tname, new Date()));
                    Thread.sleep(1000);
                    System.out.println(String.format("老司机:%s,离开停车场,时间:%s",
                            tname, new Date()));
                    // 释放锁
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        // 执行任务 1
        threadPool.submit(runnable);
        // 执行任务 2
        threadPool.submit(runnable);
        // 执行任务 3
        threadPool.submit(runnable);
        // 执行任务 4
        threadPool.submit(runnable);
        // 执行任务 5
        threadPool.submit(runnable);
        // 等线程池任务执行完之后关闭
        threadPool.shutdown();
    }
}


以上代码的执行结果如下:


微信图片_20220120181101.jpg


从上述的结果我们可以看出,当有 5 辆车同时需要进入停车场时,因为停车场的停车位只有 2 个,所以停车场最多只能容纳 2 辆车。此时我们通过 Semaphore 的 acquire 方法(阻塞等待)和 release 方法(颁发一个证书)顺利的实现了限流的功能,让停车场的车辆数始终控制在 2 辆车以下(等于或小于 2 辆车)。

相关文章
|
1月前
|
SQL Java 关系型数据库
【📕分布式锁通关指南 01】从解决库存超卖开始加锁的初体验
本文通过电商场景中的库存超卖问题,深入探讨了JVM锁、MySQL悲观锁和乐观锁的实现及其局限性。首先介绍了单次访问下库存扣减逻辑的正常运行,但在高并发场景下出现了超卖问题。接着分析了JVM锁在多例模式、事务模式和集群模式下的失效情况,并提出了使用数据库锁机制(如悲观锁和乐观锁)来解决并发问题。 悲观锁通过`update`语句或`select for update`实现,能有效防止超卖,但存在锁范围过大、性能差等问题。乐观锁则通过版本号或时间戳实现,适合读多写少的场景,但也面临高并发写操作性能低和ABA问题。 最终,文章强调没有完美的方案,只有根据具体业务场景选择合适的锁机制。
45 12
|
9月前
|
安全 Java 开发工具
Semaphore:实现一个限流器
Semaphore:实现一个限流器
79 0
|
Java 数据库
一文速通JUC中的各种锁
一文速通JUC中的各种锁
|
监控 安全 Java
【Java并发编程 九】JUC并发包下的锁
【Java并发编程 九】JUC并发包下的锁
80 0
我靠!Semaphore里面居然有这么一个大坑! (3)
我靠!Semaphore里面居然有这么一个大坑! (3)
285 0
我靠!Semaphore里面居然有这么一个大坑! (3)
深夜!小胖问我什么是读写锁?插队策略?升降级?(上)
深夜!小胖问我什么是读写锁?插队策略?升降级?
深夜!小胖问我什么是读写锁?插队策略?升降级?(上)
|
缓存 安全
深夜!小胖问我什么是读写锁?插队策略?升降级?(下)
深夜!小胖问我什么是读写锁?插队策略?升降级?
深夜!小胖问我什么是读写锁?插队策略?升降级?(下)
我靠!Semaphore里面居然有这么一个大坑! (1)
我靠!Semaphore里面居然有这么一个大坑! (1)
141 0
我靠!Semaphore里面居然有这么一个大坑! (1)
我靠!Semaphore里面居然有这么一个大坑! (2)
我靠!Semaphore里面居然有这么一个大坑! (2)
95 0
我靠!Semaphore里面居然有这么一个大坑! (2)