Semaphore
是一个计数信号量。从概念上讲,信号量维护了一组许可,每个acquire
操作都会阻塞直到有一个许可可用然后使用这个许可。每个release
相当于会添加一个许可,同时潜在
也就是释放了一个阻塞的acquire
。但是并没有一个实际的许可对象,信号量只是根据计数来采取相应的行动。
主要属性
1 | public class Semaphore implements java.io.Serializable { |
可见Semaphore
内部实现依赖于Sync,而Sync继承自AQS,并且其构造器接受可选项fair来控制使用公平还是非公平版本的信号量。
内部类
1 | abstract static class Sync extends AbstractQueuedSynchronizer { |
非公平版本1
2
3
4
5
6
7
8
9
10
11static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
}
公平版本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L;
FairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
}
acquire
1 | public void acquire() throws InterruptedException { |
release
1 | public void release(int permits) { |
没啥好讲的 也是利用AQS来实现,Semphore
初始化一个给定的值,这个值最终被作为同步状态的值,acquire
操作无论公平还是非公平版本,每次竞争获取并更新同步状态自减一
只要是int remaining = available - acquires;
剩余“许可数”大于等于0 这即可获得锁。而release
操作每次成功则将同步状态增一,相当于添加了一个“许可”。