Semaphore源码分析


title: JUC.Semaphore

Semaphore提纲

Semaphore简介

一句话介绍Semaphore就是资源的控制访问许可控制。限流听说过吧,令牌桶算法听说过呗。
所以Semaphore就是一个桶里面放入特定的令牌,当有需要访问资源的时候就去里面拿一个令牌。没了就阻塞住需要访问资源的线程。
综上Semaphore想怎么用,可以发挥想象力。想怎么玩怎么玩,比如说模仿CountDownLatch或者CyclicBarrier都不是问题。
或者搞一个限流啥的都不成问题。
因为原理都是一样
抽象出来其实还是AQS的精髓,多线程访问资源,仅满足特定条件线程可继续执行其余都排队阻塞。

Semaphore源码解析

Semaphore要不看一下类图?
Semaphore源码分析
写这个JUC我其实挺烦的每天都写一些重复的东西。。。。。
还是那么老套路AQS不想解释类图了,直接说内部实现以及重写了些啥。
Semaphore内部维护一个计数器,tryAcquireShared就减少state,tryReleaseShared就增加state。
其余的还是老套路进队列等待唤醒

//初始化permits许可个数,别以为一定就要大于0。就不能初始化为0,然后再release几次把permits加上去?
public Semaphore(int permits) {
    sync = new NonfairSync(permits);
}

//接着看一下tryAcquireShared
protected int tryAcquireShared(int acquires) {
        return nonfairTryAcquireShared(acquires);
}

final int nonfairTryAcquireShared(int acquires) {
        for (;;) {
            int available = getState();//获取AQS中state也就是permits
            int remaining = available - acquires;//减少值
            //remaining小于0直接进队列,大于0则CAS替换值然后返回
            if (remaining < 0 ||
                compareAndSetState(available, remaining))
                return remaining;
        }
}

protected final boolean tryReleaseShared(int releases) {
    for (;;) {
        int current = getState();
        int next = current + releases;//增加permits值
        if (next < current) // overflow
            throw new Error("Maximum permit count exceeded");
        if (compareAndSetState(current, next))//CAS替换state值。
            return true;
    }
}
//执行成功返回true继续到AQS唤醒因为没有许可被阻塞的线程。

Semaphore只要想明白就是一个水桶里面放了许可,干任何事情都要从里面拿一个令牌,做完往里面添加一个,
没有许可的都去排队。然后具体你要用它做什么,随你开心就好了。

欢迎扫码加入知识星球继续讨论
Semaphore源码分析