• 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、唤醒线程

  • 相关阅读:
    Rsync+inotify自动同步数据
    join和 Daemon守护线程
    多线程的简单演示
    DB2用一张表更新其他表的数据
    WebService到底是什?
    JqueryUI学习笔记-自动完成autocomplete
    DB2 SQLCODE 大全
    eclipse调试java程序的九个技巧
    Class和ClassLoader的getResourceAsStream区别
    linux下vi命令大全
  • 原文地址:https://www.cnblogs.com/benx/p/3444665.html
Copyright © 2020-2023  润新知