标签:android concurrent 多线程 并发 java
Semaphore是一个计数的信号量。从概念上来说,信号量维持一组许可(permits)。acquire方法在必须的时候都会阻塞直到有一个许可可用,然后就会拿走这个许可。release方法添加一个许可,会有可能释放一个阻塞中的获取者(acquirer)。然而,Semaphore没有使用真实的许可对象,只是保持一个可用计数并且采取相应的行为。信号量一般用于限制可以访问一些(物理上或者逻辑上)的资源的并发线程数。
信号量初始化为1的时候,意味着它最多只有一个允许可用,这样就能作为互斥独占锁使用。这种更多地被称为二进制信号量(binary semaphore),因为它只有两个状态:一个许可可用,或者0个许可可用。当使用这种方式的时候,二进制信号量就有这样的属性(不像大部分锁的实现):锁可以被拥有者(就如信号量没有拥有者的概念)之外的另外线程释放。这种属性在某些特殊的上下文中很有用,例如死锁恢复。具体实现
先来看看Semaphore的构造函数: public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
} 可以看到构造函数与ReentrantLock实现类似,都是按照fair参数分配创建不同的锁类,再来看看Semaphore的acquire和release的接口实现 public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public void release() {
sync.releaseShared(1);
} 可以看到acquire和release的实现都是调用内部类Sync的方法实现,当然了,这些方法也就是AQS提供出来的获取和释放共享锁接口。接下来看看整个实现里最主要的内部类Sync的相关实现: abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1192457210091910933L;
Sync(int permits) {
setState(permits);
}
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
protected final boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState();
int next = current + releases;
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))
return true;
}
}
//省略一些次要方法
}
/**
* 非公平版本
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;
NonfairSync(int permits) {
super(permits);
}
protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
}
/**
* 公平版本
*/
static 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;
}
}
} 为了方便了解主要逻辑,Sync类省略掉一些次要的方法。非公平版本NonfairSync类和公平版本FairSync类都继承于Sync类,Sync类继承于AQS类,NonfairSync和FairSync类都有同样的tryReleaseShared实现,只不过在tryAcquireShared实现上有稍微不同。Semaphore实现Andoird版源码剖析,布布扣,bubuko.com
标签:android concurrent 多线程 并发 java
原文地址:http://blog.csdn.net/pun_c/article/details/37875049