队列同步器  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 }

 

posted on 2017-12-11 15:56  飞奔的菜鸟  阅读(182)  评论(0编辑  收藏  举报