四.AQS的实现
2017-09-18 本文已影响0人
蜗牛1991
一.ReentrantLock
- 层次图
- ReentrantLock是独占模式,其中NonfairSync 是非公平锁,FairSync是公平锁,构造器就是构造它们,Sync定义抽象Lock方法供子类实现,unlock方法就是state减一。
public class ReentrantLock implements Lock, java.io.Serializable {
public ReentrantLock() { sync = new NonfairSync(); }
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
private final Sync sync;
abstract static class Sync extends AbstractQueuedSynchronizer { abstract void lock();}
static final class NonfairSync extends Sync { }
static final class FairSync extends Sync { }
public void unlock() {sync.release(1); }
}
- 公平锁的实现
- 回想一下上节获取锁流程(Acquire):试图获取锁(tryAcquire)若失败,则进入acquireQueued方法获取阻塞队列
- ReentrantLock获取锁方式:当state=1,若当前节点不是头结点且是阻塞队列第一个节点,并通过CAS将state值+1,阻止其他线程获取;若state!=0且为当前线程是获取锁的线程,则继续讲state+1;其他情况获取锁失败
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
//AQS方法
final void lock() {
acquire(1);
}
//AQS tryAcquire方法子类的实现
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
- 非公平锁的实现
- 回想一下上节获取锁流程(Acquire):试图获取锁(tryAcquire)若失败,则进入acquireQueued方法获取阻塞队列
- ReentrantLock获取锁方式:若state=0,当前线程尝试通过CAS看看能不能把state从0变为1(即获取锁),如果可以的话,直接获取锁而不需要排队(按队列顺序)
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
二.信号量Semaphore实现原理
- 信号量允许多条线程获取锁,它的锁是一种共享锁,信号量也有公平模式与非公平模式,与ReentrantLock类似
- 实现方式
- 通过设置permits(允许几个线程)作为初始state,没获取一次state-1,,如果返回的是一个<0的数字,那么构建FIFO队列,线程阻塞,直到前面的执行完才能唤醒后面的。
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;
}
}
三.CountDownLatch实现原理
- 传入一个count作为初始state,await的时候判断是不是0,是0返回1表示成功,返回-1表示失败,构建FIFO队列,head头只连接一个Node,Node中的线程就是调用CountDownLatch的await()方法的线程,每次countDown的时候对state-1,直到state减到0的时候才算tryReleaseShared成功,tryReleaseShared成功,唤醒被挂起的线程
private static final class Sync extends AbstractQueuedSynchronizer {
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
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;
}
}
}