Java不可重入锁和可重入锁理解[通俗易懂]

Java不可重入锁和可重入锁理解[通俗易懂]最近正在阅读JavaReentrantLock源码,始终对可重入和不可重入概念理解不透彻,进行学习后记录在这里。基础知识Java多线程的wait()方法和notify()方法这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的monitor(俗称“锁”),否则会抛出IllegalMonitorStateException异常,所以这两个方法必须在同步…

大家好,又见面了,我是你们的朋友全栈君。

最近正在阅读Java ReentrantLock源码,始终对可重入和不可重入概念理解不透彻,进行学习后记录在这里。

基础知识

Java多线程的wait()方法和notify()方法

这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的monitor(俗称“锁”),否则会抛出IllegalMonitorStateException异常,所以这两个方法必须在同步块代码里面调用。

wait():阻塞当前线程

notify():唤起被wait()阻塞的线程

不可重入锁

所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。我们尝试设计一个不可重入锁:

public class Lock{
    private boolean isLocked = false;
    public synchronized void lock() throws InterruptedException{
        while(isLocked){    
            wait();
        }
        isLocked = true;
    }
    public synchronized void unlock(){
        isLocked = false;
        notify();
    }
}

使用该锁:

public class Count{
    Lock lock = new Lock();
    public void print(){
        lock.lock();
        doAdd();
        lock.unlock();
    }
    public void doAdd(){
        lock.lock();
        //do something
        lock.unlock();
    }
}

当前线程执行print()方法首先获取lock,接下来执行doAdd()方法就无法执行doAdd()中的逻辑,必须先释放锁。这个例子很好的说明了不可重入锁。

可重入锁

接下来,我们设计一种可重入锁

public class Lock{
    boolean isLocked = false;
    Thread  lockedBy = null;
    int lockedCount = 0;
    public synchronized void lock()
            throws InterruptedException{
        Thread thread = Thread.currentThread();
        while(isLocked && lockedBy != thread){
            wait();
        }
        isLocked = true;
        lockedCount++;
        lockedBy = thread;
    }
    public synchronized void unlock(){
        if(Thread.currentThread() == this.lockedBy){
            lockedCount--;
            if(lockedCount == 0){
                isLocked = false;
                notify();
            }
        }
    }
}

所谓可重入,意味着线程可以进入它已经拥有的锁的同步代码块儿。

我们设计两个线程调用print()方法,第一个线程调用print()方法获取锁,进入lock()方法,由于初始lockedBy是null,所以不会进入while而挂起当前线程,而是是增量lockedCount并记录lockBy为第一个线程。接着第一个线程进入doAdd()方法,由于同一进程,所以不会进入while而挂起,接着增量lockedCount,当第二个线程尝试lock,由于isLocked=true,所以他不会获取该锁,直到第一个线程调用两次unlock()将lockCount递减为0,才将标记为isLocked设置为false。

可重入锁的概念和设计思想大体如此,Java中的可重入锁ReentrantLock设计思路也是这样

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153238.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月26日 下午12:00
下一篇 2022年6月26日 下午12:16


相关推荐

  • matlab中imfilter函数是什么意思_matlab中bwlabel函数

    matlab中imfilter函数是什么意思_matlab中bwlabel函数Matlab函数imfill简介函数功能:该函数用于填充图像区域和“空洞”。语法格式:BW2=imfill(BW)这种格式将一张二值图像显示在屏幕上,允许用户使用鼠标在图像上点几个点,这几个点围成的区域即要填充的区域。要以这种交互方式操作,BW必须是一个二维的图像。用户可以通过按Backspace键或者Delete键来取消之前选择的区域;通过shift+鼠标左键单击或者鼠…

    2025年11月9日
    4
  • quartus ii 9.0安装激活成功教程教程_quartusii激活成功教程教程

    quartus ii 9.0安装激活成功教程教程_quartusii激活成功教程教程其实很多时候我们用web版就够了,不用激活成功教程,不要license,很方便, web版链接:https://pan.baidu.com/s/1OSvnko0b_TEEZvQ7EeQB6A 密码:g920 点击QuartusSetupWeb-13.1.0.162.exe进行安装,安装完成以后对modelsim进行配置,将vsim.exe的路径添加到tools->options->EDATo…

    2022年10月15日
    5
  • Claude Code介紹和使用建議

    Claude Code介紹和使用建議

    2026年3月16日
    2
  • 图像修复简介

    图像修复简介点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达推荐阅读 42 个 pycharm 使用技巧 瞬间从黑铁变王者 GoogleC 项目编程风格指南

    2025年11月11日
    3
  • wget 安装yum_没有yum命令

    wget 安装yum_没有yum命令wget是一个从网络上自动下载文件的自由工具,支持通过HTTP、HTTPS、FTP三个最常见的TCP/IP下载,并可以使用HTTP代理。”wget”这个名称来源于“WorldWideWeb”与“get”的结合。在线安装wget使用命令yum-yinstallwget

    2022年10月17日
    6
  • ORACLE时间函数(SYSDATE)简单理解

    ORACLE时间函数(SYSDATE)简单理解加法 nbsp selectsysdat add months sysdate 12 fromdual 加 1 年 nbsp selectsysdat add months sysdate 1 fromdual 加 1 月 nbsp selectsysdat to char sysdate 7 yyyy mm ddHH24 MI SS fromdual 加 1 星期 nbsp sele

    2025年8月19日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号