个人博客
www.milovetingting.cn
AQS
,即 AbstractQueuedSynchronizer
,意为队列同步器,是用来构建锁或者其它同步组件的基础框架。
AQS使用一个 int
类型的 state
表示同步状态。
AQS使用了 模版方法
的设计模式,子类继承AQS后,通过实现抽象方法来管理同步状态。
AQS在 ReentrantLock
、 ReentrantReadWriteLock
、 Semaphore
、 CountDownLatch
等类中都有广泛使用。
下面以ReentrantLock为例,来看下AQS的具体使用
ReentrantLock中有一个 Sync
类型的成员变量 sync
。
private final Sync sync; 复制代码
Sync的定义
abstract static class Sync extends AbstractQueuedSynchronizer { //... } 复制代码
Sync是一个继承自AQS的抽象类,只实现了一部分的抽象方法。它有两个子类:
NonfairSync
:用于实现非公平锁
/** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; /** * Performs lock. Try immediate barge, backing up to normal * acquire on failure. */ final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } 复制代码
FairSync
:用于实现公平锁
/** * Sync object for fair locks */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ 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; } } 复制代码
在Sync的子类实现中,主要用到了 getState()
、 setState(int newState)
、 compareAndSetState(int expect,int update)
方法。
protected final int getState() { return state; } 复制代码
protected final void setState(int newState) { state = newState; } 复制代码
protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } 复制代码
通过 CAS
来实现同步操作。
在使用ReentrantLock时,默认是 非公平锁
public ReentrantLock() { sync = new NonfairSync(); } 复制代码
我们也可以指定使用公平锁或非公平锁
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); } 复制代码
CLH
队列锁即Craig, Landin, and Hagersten (CLH) locks。
CLH队列锁也是一种基于 链表
的可扩展、高性能、公平的自旋锁,申请线程仅仅在本地变量上自旋,它不断轮询前驱的状态,假设发现前驱释放了锁就结束自旋。
下面基于AQS实现一个自定义的锁
Lock
接口 public class CustomLock implements Lock { @Override public void lock() { } @Override public void lockInterruptibly() throws InterruptedException { } @Override public boolean tryLock() { return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } @Override public void unlock() { } @Override public Condition newCondition() { return null; } } 复制代码
可以看到,实现Lock后,生成的默认方法如上。
tryAcquire
、 tryRelease
、 isHeldExclusively
方法 private static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } @Override protected boolean tryRelease(int arg) { if (getState() == 0) { throw new IllegalMonitorStateException(); } setExclusiveOwnerThread(null); setState(0); return true; } @Override protected boolean isHeldExclusively() { return getState() == 1; } Condition newCondition() { return new ConditionObject(); } } 复制代码
private Sync sync = new Sync(); @Override public void lock() { System.out.println(Thread.currentThread().getName() + " ready get lock"); sync.acquire(1); System.out.println(Thread.currentThread().getName() + " already got lock"); } @Override public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } @Override public boolean tryLock() { return sync.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(time)); } @Override public void unlock() { System.out.println(Thread.currentThread().getName() + " ready release lock"); sync.release(1); System.out.println(Thread.currentThread().getName() + " already released lock"); } @Override public Condition newCondition() { return sync.newCondition(); } 复制代码
Lock lock = new CustomLock(); try{ lock.lock(); //执行具体的业务 } catch(Exception e){ e.printStackTrace(); } finally{ lock.unlock(); } 复制代码
以上4步,即可以实现简单的自定义锁。
public class CustomLock implements Lock { private Sync sync = new Sync(); @Override public void lock() { System.out.println(Thread.currentThread().getName() + " ready get lock"); sync.acquire(1); System.out.println(Thread.currentThread().getName() + " already got lock"); } @Override public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } @Override public boolean tryLock() { return sync.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(time)); } @Override public void unlock() { System.out.println(Thread.currentThread().getName() + " ready release lock"); sync.release(1); System.out.println(Thread.currentThread().getName() + " already released lock"); } @Override public Condition newCondition() { return sync.newCondition(); } private static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } @Override protected boolean tryRelease(int arg) { if (getState() == 0) { throw new IllegalMonitorStateException(); } setExclusiveOwnerThread(null); setState(0); return true; } @Override protected boolean isHeldExclusively() { return getState() == 1; } Condition newCondition() { return new ConditionObject(); } } } 复制代码
和上面的步骤差不多,只需要在继承AQS的类的实现方法中修改即可
private static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } else if (getExclusiveOwnerThread() == Thread.currentThread()) { setState(getState() + 1); return true; } return false; } @Override protected boolean tryRelease(int arg) { if (getExclusiveOwnerThread() != Thread.currentThread()) { throw new IllegalMonitorStateException(); } if (getState() == 0) { throw new IllegalMonitorStateException(); } setState(getState() - 1); if (getState() == 0) { setExclusiveOwnerThread(null); } return true; } @Override protected boolean isHeldExclusively() { return getState() > 0; } Condition newCondition() { return new ConditionObject(); } } 复制代码
完整代码
public class CustomReentrantLock implements Lock { private Sync sync = new Sync(); @Override public void lock() { System.out.println(Thread.currentThread().getName() + " ready get lock"); sync.acquire(1); System.out.println(Thread.currentThread().getName() + " already got lock"); } @Override public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } @Override public boolean tryLock() { return sync.tryAcquire(1); } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(time)); } @Override public void unlock() { System.out.println(Thread.currentThread().getName() + " ready release lock"); sync.release(1); System.out.println(Thread.currentThread().getName() + " already released lock"); } @Override public Condition newCondition() { return sync.newCondition(); } private static class Sync extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int arg) { if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } else if (getExclusiveOwnerThread() == Thread.currentThread()) { setState(getState() + 1); return true; } return false; } @Override protected boolean tryRelease(int arg) { if (getExclusiveOwnerThread() != Thread.currentThread()) { throw new IllegalMonitorStateException(); } if (getState() == 0) { throw new IllegalMonitorStateException(); } setState(getState() - 1); if (getState() == 0) { setExclusiveOwnerThread(null); } return true; } @Override protected boolean isHeldExclusively() { return getState() > 0; } Condition newCondition() { return new ConditionObject(); } } } 复制代码