java Semaphore 信号量理解与示例

是什么

给定一定数量的许可证,用于调用者获取,如果许可证都被占用,那么就进入阻塞状态;
可以理解为上公共厕所,厕所只有2个坑位,目前有3个人,那么同时只能有2个人进去,第三人想要进去那么就必须等占用坑位的人完事之后才OK
目前在业务上没遇到信号量场景,能想到的就是对单体应用请求限流,下面就给出一个示例

使用信号量限流示例

import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 *
 * 信号量实现限流示例
 * @author 唐海斌
 * @date 2022/8/17 13:24
 */
public class SemaphoreLimit {
    /**
     * 同时允许2个客户端同时访问资源
     */
    static Semaphore semaphore = new Semaphore(2);

    public static void limit()  {
        try {
            //当未获取到许可会阻塞,直到有新的许可
            semaphore.acquire();
            System.out.println(LocalDateTime.now() + "------>>>> 获取到许可...");
            //将线程阻塞10秒,模拟业务处理
            LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(10));
            semaphore.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int index = 0; index < 10; ++index) {
            executorService.execute(SemaphoreLimit::limit);
        }
    }
}

原理

从源码上分析

 abstract static class Sync extends AbstractQueuedSynchronizer {
    //非公平信号量实现
    final int nonfairTryAcquireShared(int acquires) {
        for (; ; ) {
            //获取可用许可数量
            int available = getState();
            //剩余许可数 = 可用许可数 - 请求许可数
            int remaining = available - acquires;
            //可用许可数小于0直接返回,在调用方死循环调用当前方法;可用许可数大于0就采用CAS比较更新剩余许可数的值
            if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                return remaining;
        }
    }
}

总结

内部实现了AQS同步器,采用许可数递减的方式发放许可,当许可数小于1就死循环获取许可直到有空闲的许可证;所以能限制在同一时间内最多有指定数量的线程可以访问资源

posted @   四码难追  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示