public class Semaphore implements java.io.Serializable 复制代码
2. 字段属性
//序列化版本号 private static final long serialVersionUID = -3222578661600680210L; //同步器,AbstractQueuedSynchronizer的子类 private final Sync sync; 复制代码
从字段属性中可以看出
- Semaphore的所有操作都是使用内部类Sync对象进行操作的
3. 构造方法
//传入信号数 public Semaphore(int permits) { //默认使用非公平锁 sync = new NonfairSync(permits); } //传入信号数和锁的类型 public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); } 复制代码
从构造方法中可以看出
- 构造方法只做了一件事:初始化sync对象
4.方法
acquire 方法
//可中断的获取信号量
public void acquire() throws InterruptedException {
//调用sync的acquireSharedInterruptibly方法
sync.acquireSharedInterruptibly(1);
}
//获取指定数量的信号量
public void acquire(int permits) throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
//调用sync的acquireSharedInterruptibly方法
sync.acquireSharedInterruptibly(permits);
}
复制代码
acquireUninterruptibly 方法
//不可中断的获取信号量 public void acquireUninterruptibly() { //调用sync的acquireShared方法 sync.acquireShared(1); } //不可中断的获取指定数量的信号量 public void acquireUninterruptibly(int permits) { if (permits < 0) throw new IllegalArgumentException(); sync.acquireShared(permits); } 复制代码
tryAcquire 方法
//尝试获取信号量
public boolean tryAcquire() {
//调用sync的nonfairTryAcquireShared方法
return sync.nonfairTryAcquireShared(1) >= 0;
}
//尝试获取指定数量的信号量
public boolean tryAcquire(int permits) {
if (permits < 0) throw new IllegalArgumentException();
//尝试获取指定数量的信号量
return sync.nonfairTryAcquireShared(permits) >= 0;
}
//设置超时时间的尝试获取信号量
public boolean tryAcquire(long timeout, TimeUnit unit)
throws InterruptedException {
//调用sync的tryAcquireSharedNanos方法
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//设置超时时间的尝试获取指定数量的信号量
public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
throws InterruptedException {
if (permits < 0) throw new IllegalArgumentException();
//调用sync的tryAcquireSharedNanos方法
return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
}
复制代码
release 方法
//释放一个信号量 public void release() { //调用sync的releaseShared方法 sync.releaseShared(1); } //释放指定数量的信号量 public void release(int permits) { if (permits < 0) throw new IllegalArgumentException(); sync.releaseShared(permits); } 复制代码
availablePermits 方法
//获取当前可用的通道数 public int availablePermits() { return sync.getPermits(); } 复制代码
drainPermits 方法
//获取立即可用的通道数 public int drainPermits() { return sync.drainPermits(); } 复制代码
reducePermits 方法
//减少信号数 protected void reducePermits(int reduction) { if (reduction < 0) throw new IllegalArgumentException(); sync.reducePermits(reduction); } 复制代码
isFair 方法
//获取锁的类型, true 公平锁, false 非公平锁 public boolean isFair() { return sync instanceof FairSync; } 复制代码
hasQueuedThreads 方法
//队列中是否有正在等信号的线程
public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
复制代码
getQueueLength 方法
//获取队列中等待信号的线程数 public final int getQueueLength() { return sync.getQueueLength(); } 复制代码
getQueuedThreads 方法
//获取队列中的线程,以集合的方式返回
protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
}
复制代码
5. 内部类Sync
1. 类的定义
abstract static class Sync extends AbstractQueuedSynchronizer 复制代码
从类的定义中可以看出
- Sync是一个抽象的静态内部类,使用模板方法的设计模式让子类继承
- Sync继承AbstractQueuedSynchronizer类
2. 字段属性
//序列化版本号 private static final long serialVersionUID = 1192457210091910933L; 复制代码
3. 构造方法
//传入的信号数就是AQS中的state Sync(int permits) { setState(permits); } 复制代码
4. 方法
getPermits 方法
//获取信号数 final int getPermits() { //实质上就是获取state的值 return getState(); } 复制代码
nonfairTryAcquireShared 方法
//非公平方式获取共享锁,返回剩余可用信号数 final int nonfairTryAcquireShared(int acquires) { //for无限循环,自旋CAS for (;;) { //获取当前的state int available = getState(); //可用信号-获取数量=剩余可用数量 int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } 复制代码
tryReleaseShared 方法
//尝试释放共享锁 protected final boolean tryReleaseShared(int releases) { //for无限循环,自旋CAS for (;;) { //获取当前的state int current = getState(); //可用信号+释放数量=新的可用数量 int next = current + releases; if (next < current) // overflow //releases小于0 抛出异常 throw new Error("Maximum permit count exceeded"); //CAS,设置新值 if (compareAndSetState(current, next)) return true; } } 复制代码
reducePermits 方法
//减少信号数量 final void reducePermits(int reductions) { //for无限循环,自旋CAS for (;;) { //获取当前的state int current = getState(); //可用信号-减少的数量=新的可用数量 int next = current - reductions; if (next > current) // underflow //reductions小于0 抛出异常 throw new Error("Permit count underflow"); //CAS,设置新值 if (compareAndSetState(current, next)) return; } } 复制代码
drainPermits 方法
//清空信号 final int drainPermits() { //CAS 自旋把state置为0 for (;;) { int current = getState(); if (current == 0 || compareAndSetState(current, 0)) return current; } } 复制代码
6. 内部类 NonfairSync
1. 类的定义
static final class NonfairSync extends Sync 复制代码
从类的定义可以看出
- NonfairSync是Sync的子类
2. 字段属性
//序列化版本号 private static final long serialVersionUID = -2694183684443567898L; 复制代码
3. 构造方法
//设置state NonfairSync(int permits) { super(permits); } 复制代码
4. 方法
tryAcquireShared 方法
//尝试获取共享锁 protected int tryAcquireShared(int acquires) { //调用父类的方法nonfairTryAcquireShared,直接抢锁 return nonfairTryAcquireShared(acquires); } 复制代码
7. 内部类FairSync
1. 类的定义
static final class FairSync extends Sync 复制代码
从类的定义中可以看出
- FairSync继承Sync类
2. 字段属性
//序列化版本号 private static final long serialVersionUID = 2014338818796000944L; 复制代码
3. 构造方法
//设置state FairSync(int permits) { super(permits); } 复制代码
方法
tryAcquireShared 方法
//尝试获取共享锁 protected int tryAcquireShared(int acquires) { for (;;) { //先看队列中是否有线程排队 if (hasQueuedPredecessors()) return -1; //获取state的值 int available = getState(); //可用信号-获取数量=剩余可用数量 int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } } 复制代码
原文
https://juejin.im/post/5e6f654d6fb9a07cd52bf954
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java 并发编程(十五) — Semaphore源码分析