AQS理解之六,AQS的其他实现类
1,ThreadPoolExecutor 中的 Worker 类
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
重写了这几个方法,可以看出来实现的是一个不可重入的锁。
2,Semaphore 信号量类
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1192457210091910933L;
Sync(int permits) {
setState(permits);
}
final int getPermits() {
return getState();
}
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;
}
}
final void reducePermits(int reductions) {
for (;;) {
int current = getState();
int next = current - reductions;
if (next > current) // underflow
throw new Error("Permit count underflow");
if (compareAndSetState(current, next))
return;
}
}
final int drainPermits() {
for (;;) {
int current = getState();
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
}
使用state的数量来代表信号量已经使用的数,如果大于0,则可以进入,如果小于等于0,则阻塞住,不能获取到信号量。
和ReentrantLock有点类似,如果acquire时不能进入,则阻塞,并加入链表,在release时会将阻塞的节点unpark打开。
3,CountDownLatch
首先看下CountDownLatch的构造使用
CountDownLatch countDownLatch = new CountDownLatch(5);//构造
countDownLatch.countDown();//计数
countDownLatch.await();//等待完成
//构造时,实际上是设置了state为一个数。
Sync(int count) {
setState(count);
}
//这里实际上就是一个release操作,每次都会将state原子性减一,并顺便会将阻塞的节点unpark打开。
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
//await方法实际上是计算state是否为0,如果不为0,则park阻塞等待直到为0
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
使用state表示仍需要执行的次数,当为0时结束阻塞
总结
AQS实现了一套公共的实现Java锁的逻辑,我们可以继承它来实现自己在多线程下的锁。