首页 > 代码库 > ReentrantLock源码了解

ReentrantLock源码了解

    1)、ReentrantLock.tryLock    //获取没有被其他线程持有的锁    //1)、当没有被任何线程持有时,首先将计数器设置为1,并设置当前持有锁的线程为当前线程,最后返回true    //2)、当被当前线程持有时,将计数器加1,最后返回true;    //3)、否则返回false    public boolean tryLock() {        return sync.nonfairTryAcquire(1);    }    //接着直接调用抽象类中的Sync.nonfairTryAcquire    final boolean nonfairTryAcquire(int acquires) {        //获取当前调用线程        final Thread current = Thread.currentThread();        //获取当前锁的状态,也就是当前锁的计数器的数值        int c = getState();        if (c == 0) {            //此时说明,当前锁没有被任何线程持有            if (compareAndSetState(0, acquires)) {                //使用CAS操作,更新锁的状态,即锁的计数器的数值,若是成功,则将当前锁的线程持有者设置为当前线程                setExclusiveOwnerThread(current);                return true;            }        }        else if (current == getExclusiveOwnerThread()) {            //根据JMM模型可知,同一个工作内存内是可见的,故同一个线程内是可见的,若相等,是同一个线程,且在同一个线程内不会发生setExclusiveOwnerThread时,在getExclusiveOwnerThread得到的不一样            //此时说明,当前锁的线程持有者是当前线程            //设置锁的计数器的值            int nextc = c + acquires;            if (nextc < 0) // overflow                throw new Error("Maximum lock count exceeded");            //更新锁的状态,即锁的计数值的数值            setState(nextc);            return true;        }        return false;    }    2)、ReentrantLock.unlock    //试图释放锁    //1)、当前线程不是该锁的持有者时,抛出异常    //2)、当前锁的计数器更改为0时,则设置当前锁的持有者为null    //3)、否则,更新当前锁的状态,即锁的计数器的数值    public void unlock() {        sync.release(1);    }    //接着直接调用抽象类AbstractQueuedSynchronizer.release    public final boolean release(int arg) {        if (tryRelease(arg)) {            //当锁的状态为0,或者说当前锁没有持有者时,需要唤醒当前锁上挂起的线程            Node h = head;            if (h != null && h.waitStatus != 0)                unparkSuccessor(h);            return true;        }        return false;    }    //再接着直接调用抽象类Sync.tryRelease    protected final boolean tryRelease(int releases) {        //计算当前锁的计数器的数值        int c = getState() - releases;        //判断当前线程是否是锁的持有者,若不是,则抛出异常        if (Thread.currentThread() != getExclusiveOwnerThread())            throw new IllegalMonitorStateException();        boolean free = false;        if (c == 0) {            //当计数器的数值为0,说明此时锁没有持有者了,故先更新线程持有者,之后再去更新锁的状态,这样当去获取锁的状态时,此时的锁的持有者必然是更新后的,这样锁的释放和锁的获取就能保证一致的可见性了。            free = true;            setExclusiveOwnerThread(null);        }        //更新锁的状态,即锁的计数器的数值        setState(c);        return free;    }    //直接调用AbstractQueuedSynchronizer.unparkSuccessor    //唤醒当前节点后的第一个非取消节点中的线程    private void unparkSuccessor(Node node) {                //尝试更新当前节点的状态        int ws = node.waitStatus;        if (ws < 0)            compareAndSetWaitStatus(node, ws, 0);        //获取当前节点后的第一个非取消节点,并唤醒该节点中挂起的线程        Node s = node.next;        if (s == null || s.waitStatus > 0) {            s = null;            //从尾节点开始查找,直到当前节点,即可得到一个当前节点后的第一个非取消节点            for (Node t = tail; t != null && t != node; t = t.prev)                if (t.waitStatus <= 0)                    s = t;        }        //唤醒线程        if (s != null)            LockSupport.unpark(s.thread);    }    3)、ReentrantLock.lock    //申请锁    public void lock() {       sync.lock();    }    31)、非公平锁    //直接调用NonfairSync.lock    final void lock() {        //当通过CAS判断当前锁是否没有持有者,若是,则直接设置当前锁的持有者为当前线程;        //否则,再次尝试加锁,最后还不成功,就如等待队列,线程挂起,直到被唤醒为止        if (compareAndSetState(0, 1))            setExclusiveOwnerThread(Thread.currentThread());        else            acquire(1);    }    //直接调用AbstractQueuedSynchronizer.acquire    public final void acquire(int arg) {        //尝试获取非公平锁,当失败时,就将当前线程入等待队列,线程挂起,直到被挂起        if (!tryAcquire(arg) &&            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))            selfInterrupt();    }    //直接调用NonfairSync.tryAcquire       protected final boolean tryAcquire(int acquires) {           //尝试获取非公平锁        return nonfairTryAcquire(acquires);    }    //直接调用AbstractQueuedSynchronizer.addWaiter    //将排他锁节点添加到链表尾部    private Node addWaiter(Node mode) {        Node node = new Node(Thread.currentThread(), mode);        // Try the fast path of enq; backup to full enq on failure        Node pred = tail;        if (pred != null) {            //当前链表已经初始化,则CAS尝试将排他锁节点更改为链表的尾节点            //设置当前节点的前一个节点为当前链表的尾节点            node.prev = pred;            //当CAS尝试更新尾节点成功,则将新尾节点的前一个节点的下一个节点更新为新的尾节点            if (compareAndSetTail(pred, node)) {                pred.next = node;                return node;            }        }        enq(node);        return node;    }    //直接调用AbstractQueuedSynchronizer.compareAndSetTail    //原子更新链表的尾节点    private final boolean compareAndSetTail(Node expect, Node update) {        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);    }    //直接调用AbstractQueuedSynchronizer.enq    //使用CAS原子性将节点插入到链表尾部    private Node enq(final Node node) {        for (;;) {            Node t = tail;            if (t == null) { // Must initialize                //当没有初始化时,进行头结点与尾节点初始化,成功后,将头结点与尾节点指向同一个处对象                if (compareAndSetHead(new Node()))                    tail = head;            } else {                //将节点插入到链表尾部                //设置当前节点的前一个节点为当前链表的尾节点                node.prev = t;                //当CAS尝试更新尾节点成功,则将新尾节点的前一个节点的下一个节点更新为新的尾节点                if (compareAndSetTail(t, node)) {                    t.next = node;                    return t;                }            }        }    }    //直接调用AbstractQueuedSynchronizer.acquireQueued    //当当前节点为等待队列中的第一个节点时,获取到锁    final boolean acquireQueued(final Node node, int arg) {        boolean failed = true;        try {            boolean interrupted = false;            for (;;) {                //当当前节点的前节点为头结点,并为当前线程尝试获取锁,成功时,设置当前节点为头结点,并将当前节点的前节点的下一个节点取消,使之没有被引用,这样可以被GC回收                final Node p = node.predecessor();                if (p == head && tryAcquire(arg)) {                    setHead(node);                    p.next = null; // help GC                    failed = false;                    return interrupted;                }                    //设置当前节点的前节点状态为唤醒状态,且将当前节点挂起                if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())                    interrupted = true;            }        } finally {            if (failed)                cancelAcquire(node);        }    }    //直接调用AbstractQueuedSynchronizer.setHead    //设置当前节点为头结点,并将当前节点的前节点置为空,以及将当前节点持有的线程设置为空    private void setHead(Node node) {        head = node;        node.thread = null;        node.prev = null;    }    //直接调用AbstractQueuedSynchronizer.shouldParkAfterFailedAcquire    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {        int ws = pred.waitStatus;        if (ws == Node.SIGNAL)            //当当前节点的前节点状态为唤醒时,则表明下一个被执行的节点是当前节点,即线程会被唤醒            return true;        if (ws > 0) {               //当当前节点的前节点为取消的节点,则往前查找一个非取消的节点            do {                node.prev = pred = pred.prev;            } while (pred.waitStatus > 0);            //将查找的非取消节点的下一个节点更新为当前节点            pred.next = node;        } else {            //尝试将当前节点的前节点的状态设置为唤醒状态            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);        }        return false;    }    //直接调用AbstractQueuedSynchronizer.compareAndSetWaitStatus       //尝试更新节点的状态    private static final boolean compareAndSetWaitStatus(Node node, int expect, int update) {        return unsafe.compareAndSwapInt(node, waitStatusOffset, expect, update);    }    //直接调用AbstractQueuedSynchronizer.parkAndCheckInterrupt    //将当前线程挂起    private final boolean parkAndCheckInterrupt() {        LockSupport.park(this);        return Thread.interrupted();    }    

 

ReentrantLock源码了解