前面一章LZ简单的介绍了下AbstractQueuedSynchronizer(AQS)以及AQS中提供的一些模板方法和做用,这一章LZ将用一个简单的实例来介绍下AQS中独占锁的工做原理。独占锁顾名思义就是在同一时刻只能有一个线程能获取到锁,而其它须要获取这把锁的线程将进入到同步队列中等待获取到了锁的线程释放这把锁,只有获取锁的线程释放了锁,同步队列中的线程才能获取锁。LZ能够描述的有些绕,画图来解释下这段话的意思:java
这个图则清晰的说明了AQS中独占锁的的基本原理,下面LZ将用一段简单的代码来看看AQS中独占锁的工做原理。面试
public class ExclusiveDemo implements Lock { // 静态内部类,自定义同步器 private static class Sync extends AbstractQueuedSynchronizer{ // 是否处于独占状态 @Override protected boolean isHeldExclusively() { return this.getState() == 1; } // 当状态为0时,获取锁 @Override protected boolean tryAcquire(int arg) { if(compareAndSetState(0,1)){ setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } // 释放锁,将状态设置为0 @Override protected boolean tryRelease(int arg) { if(getState() == 0) throw new IllegalMonitorStateException(); setExclusiveOwnerThread(null); setState(0); return true; } // 返回一个Condition,没给Condition都包含了一个Condition队列 Condition newCondition() { return new ConditionObject(); } } private final Sync sync = new Sync(); @Override public void lock() { sync.acquire(1); } @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.tryAcquireSharedNanos(1,unit.toNanos(time)); } @Override public void unlock() { sync.release(0); } @Override public Condition newCondition() { return sync.newCondition(); } }
上面示例中,独占所ExclusiveDemo是一个自定义的同步组件,它在同一时刻只容许一个线程占有锁。ExclusiveDemo定义了一个静态内部类,该内部类继承了同步器并实现了独占式获取和释放同步状态。在tryAcquire方法中,经过CAS方式设置同步器状态,若是设置成功,返回true,设置失败返回false。tryRelease(int arg)方法是将同步器状态设置为0。经过上面的示例,我么能够看到,当咱们在使用ExclusiveDemo的时候,咱们并无直接和同步器打交道,而是经过调用ExclusiveDemo提供的方法。这一章LZ只是简单的介绍了下AQS是如何工做的,下一章LZ分析下AQS中CHL的工做原理。ide
关注下面公众号,回复
1024
领取最新大厂面试资料ui