队列同步器 AbstractQueuedSynchronizer,是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量,通过内置的FIFO队列来完成资源获取线程的排队工作。
同步器的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态。
同步器是实现锁(任意同步组件)的的关键,在锁的实现中聚合同步器,利用同步器实现锁的语义。
同步器的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模板方法,而这些模板方法将会调用使用者重写的方法。getState()、setState(int newState)、compareAndSetState(int expect, int update)。
下面,通过独占锁的示例来深入了解同步器的工作原理:
1 class Mutex implements Lock{ 2 //静态内部类,自定义同步器 3 private static class Sync extends AbstractQueuedSynchronizer{ 4 //是否处于占用状态 5 protected boolean isHeldExclusively(){ 6 return getState() == 1; 7 } 8 //当状态为0的时候获取锁 9 public boolean tryAcquire(int acquires){ 10 if (compareAndSetState(0,1)){ 11 setExclusiveOwnerThread(Thread.currentThread());//设置当前拥有独占访问的线程。null 参数表示没有线程拥有访问。 12 return true; 13 } 14 return false; 15 } 16 //释放锁,将状态设置为0 17 protected boolean tryRelease(int releases){ 18 if (getState() == 0) throw new IllegalMonitorStateException(); 19 setExclusiveOwnerThread(null); 20 setState(0); 21 return true; 22 } 23 //返回一个Condition,每个condition都包含了一个condition队列 24 Condition newCondition(){return new ConditionObject();} 25 } 26 //仅需要将操作代理到Sync上即可 27 private final Sync sync = new Sync(); 28 public void lock(){sync.acquire(1);}// 以独占模式获取对象,忽略中断。 29 public boolean tryLock(){return sync.tryAcquire(1);} 30 public void unlock(){sync.release(1);} 31 public Condition newCondition(){return sync.newCondition();} 32 public boolean isLocked(){return sync.isHeldExclusively();} 33 public boolean hasQueuedThreads(){return sync.hasQueuedThreads();} 34 public void lockInterruptibly() throws InterruptedException{ 35 sync.acquireInterruptibly(1); 36 } 37 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException{ 38 return sync.tryAcquireNanos(1,unit.toNanos(timeout)); 39 } 40 }