可重入锁

作者: high_m | 来源:发表于2017-09-09 19:49 被阅读0次

可重入锁表示如果你已经获取了锁,如果你想再次获取该锁,依然能够正常获取到,不会因为之前已经获取过还没释放而阻塞。synchronized关键字是隐式的可重入锁,表现在synchronized修饰的同步方法内递归调用自己不会阻塞。jdk中实现Lock接口的可重入锁ReentrantLock是如何实现可重入的呢?在阅读这篇文章之前,我假设你已经读过Lock内的同步器,对锁的实现有一定的了解。

可重入锁实现要点

  • 获取锁后,再次获取该锁时;判断当前线程是否是已经获取锁的线程,若是,则通过;否则,阻塞。
  • 释放锁时,如果该线程获取了n(n>=1)次锁,则需要释放n次,才能释放成功,返回true;否则,返回false。

代码实现

  • 获取可重入锁(非公平锁)同步状态的局部代码如下:
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {//此时,锁未被获取
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //当前线程就是此时占有锁的线程
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

代码中发现,如果当前线程就是已经占有锁的线程,则同步状态值进行增加,并返回true。


  • 释放可重入锁(非公平锁)的局部代码如下:
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            //当前线程不是占有锁的线程
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;//同步状态值为初始值0时,返回true;否则,返回false
        }

代码中发现同步状态值0是锁是否成功释放的标志。


  • 获取可重入锁(公平锁)的局部代码如下:
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                  //当前节点是否有前驱节点
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

与非公平锁获取同步状态相比,唯一的区别是判断引用当前线程的当前节点是否有前驱节点,如果返回true,说明有更早的节点在等待获取锁,则当前节点需要等到前驱节点获取并释放锁后才能够继续获取锁。至于释放锁,与非公平锁并无区别。

参考

  1. 并发编程的艺术

相关文章

  • ReentrantLock 源码分析

    锁的基本概念 可重入锁 Reentrant 就是可重入的意思,如果锁具备可重入性,则称作为可重入锁。像synchr...

  • java可重入锁

    可重入概念: java的可重入锁: 可重入锁的一种实现方式: 可重入锁的两种使用例子: 例子1: 例子2: 例子1...

  • Java 可重入锁 公平锁 读写锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁。 像synchronized和ReentrantLock都是可...

  • Java中的各种锁

    一个线程中的多个流程能不能获取同一把锁:可重入锁和非可重入锁 可重入锁 可重入性:表明了锁的分配机制,是基于线程的...

  • 可重入锁和非可重入锁

    1 可重入锁 (ReentrantLock和synchronized)可重入锁指的是可重复可递归调用的锁,在外层使...

  • J.U.C-AQS-ReentrantLock

    ReentrantLock(可重入锁)和synchronized区别 可重入性 锁的实现(ReentrantLoc...

  • Java温故而知新之Lock与Synchronized

    两者比较: 相关概念解析 可重入锁如果锁具备可重入性,则称作为可重入锁。假设方法A需要获取锁,方法B也需要获取锁,...

  • 可重入锁-面试题:synchronized是可重入锁吗?

    前言 面试题:synchronized是可重入锁吗? 答案:synchronized是可重入锁。Reentrant...

  • 可重入锁-synchronized是可重入锁吗?Reentran

    前言 面试题:synchronized是可重入锁吗? 答案:synchronized是可重入锁。Reentrant...

  • 各种锁的概念

    锁的概念 可重入不可重入公平锁非公平锁锁中断通过一个故事理解可重入锁的机制 - 小勇DW3 - 博客园[https...

网友评论

    本文标题:可重入锁

    本文链接:https://www.haomeiwen.com/subject/ebjajxtx.html