ReentrantLock 解读

ReentrantLock  非公平锁

lock:
    如果stage==0 或 线程为当前线程 则 设置state=state+1 ,设置当前线程为独占线程
    如果state不为0,且独占线程不是当前线程则:
        如果tail为null,设置tail和head为new Node()
        addWaiter(Node.EXCLUSIVE)  新加一个独占Node,把该Node添加到链表的尾部
        acquireQueued(Node)在for(;;)中执行
            如果node节点的上一个节点为head且tryAcquire为true,则设置node为head(获得了锁,同时删除了上一个节点)
            如果不是,则设置node节点的状态为Node.SIGNAL返回true,否者设置上一个节点状态为Node.SIGNAL,然后part线程,等待唤醒,继续执行for循环。        

Release:
    设置state=state-1,如果state为0,设置独占线程为null
    找到head,如果head不为null,且head.waitStatus不为0(一般为Node.SIGNAL -1)则执行unparkSuccessor,找到head节点的next节点(该节点waitstatus为-1或0,如果节点状态为1取消的节点,会跳过),然后唤醒该节点



newCondition:
    创建一个ConditionObject对象,该对象是内部类,共享Syn的状态,对象内部维护一个链表有firstWaiter 和 lastWaiter




condition.await
    1、addConditionWaiter 添加一个节点new Node(Thread.currentThread(), Node.CONDITION),如果lastWaiter为null,那么firstWaiter 和 lastWaiter都为该node,否者把节点添加到lastWaiter后面,并设置为lastWaiter
    2、执行releasegetState()
    3、阻塞线程
    4、如果线程被唤醒,执行acquireQueued,把线程加入lock等待队列
    

condition.signal
    1、找到firstWaiter节点 先compareAndSetWaitStatus(node, Node.CONDITION, 0)
    2、把节点加入到tail节点的末尾
    3、设置节点的状态为Node.SIGNAL
    4、唤醒线程

posted @ 2013-11-26 23:46  benx621  阅读(229)  评论(0编辑  收藏  举报