Semaphore源码分析
title: JUC.Semaphore
Semaphore提纲
Semaphore简介
一句话介绍Semaphore就是资源的控制访问许可控制。限流听说过吧,令牌桶算法听说过呗。
所以Semaphore就是一个桶里面放入特定的令牌,当有需要访问资源的时候就去里面拿一个令牌。没了就阻塞住需要访问资源的线程。
综上Semaphore想怎么用,可以发挥想象力。想怎么玩怎么玩,比如说模仿CountDownLatch或者CyclicBarrier都不是问题。
或者搞一个限流啥的都不成问题。
因为原理都是一样
抽象出来其实还是AQS的精髓,多线程访问资源,仅满足特定条件线程可继续执行其余都排队阻塞。
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只要想明白就是一个水桶里面放了许可,干任何事情都要从里面拿一个令牌,做完往里面添加一个,
没有许可的都去排队。然后具体你要用它做什么,随你开心就好了。
欢迎扫码加入知识星球继续讨论