可重入锁和不可重入锁的区别

可重入锁和不可重入锁的区别不可重入锁示例(同一个线程不可以重入上锁后的代码段)如下是一个不可重入锁的逻辑过程,会发现执行main方法控制台会打印执行doJob方法前,然后就会一直线程阻塞,不会打印执行doJob方法过程中,原因在于第一次上锁后,由于没有释放锁,因此执行第一次lock后isLocked=true,这个时候调用doJob()内部又一次调用了lock()由于上个线程将isLocked=true,导致再次进入的时候就进入死循环。导致线程无法执行System.out.println(“执行doJob方法过程中”);这

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

不可重入锁示例(同一个线程不可以重入上锁后的代码段)

如下是一个不可重入锁的逻辑过程,会发现执行main方法控制台会打印执行doJob方法前,然后就会一直线程阻塞,不会打印执行doJob方法过程中,原因在于第一次上锁后,由于没有释放锁,因此执行第一次lock后isLocked = true,这个时候调用doJob()内部又一次调用了lock()由于上个线程将isLocked = true,导致再次进入的时候就进入死循环。导致线程无法执行System.out.println("执行doJob方法过程中");这行代码,因此控制台只能打印执行doJob方法前。这种现象就造成了不可重入锁

public class Count{ 
   
    MyLock lock = new MyLock();

    public static void main(String[] args) throws InterruptedException { 
   
        new Count().doSomeThing(); // 示例的main方法
    }
    public void doSomeThing() throws InterruptedException { 
   
        lock.lock(); // 第一次上锁
        System.out.println("执行doJob方法前");
        doJob(); // 方法内会再次上锁
        lock.unlock(); // 释放第一次上的锁
    }
    public void doJob() throws InterruptedException { 
   
        lock.lock();
        System.out.println("执行doJob方法过程中");
        lock.unlock();
    }
}

/** * 自定义锁 */
class MyLock{ 
   
    private boolean isLocked = false;
    public synchronized void lock() throws InterruptedException{ 
   
        while(isLocked){ 
   
            wait();
        }
        isLocked = true; // 线程第一次进入后就会将器设置为true,第二次进入是就会由于where true进入死循环
    }
    public synchronized void unlock(){ 
   
        isLocked = false;   // 将这个值设置为false目的是释放锁
        notify();           // 接触阻塞
    }
}

可重入锁示例(同一个线程可以重入上锁的代码段,不同的线程则需要进行阻塞)

java的可重入锁有:ReentrantLock(显式的可重入锁)synchronized(隐式的可重入锁)

可重入锁诞生的目的就是防止上面不可重入锁的那种情况,导致同一个线程不可重入上锁代码段。

目的就是让同一个线程可以重新进入上锁代码段。

设计可重入锁的示例代码

public class MyReentrantLock { 
   
    boolean isLocked = false;   // 默认没有上锁
    Thread lockedBy = null; // 记录阻塞线程
    int lockedCount = 0;    // 上锁次数计数

    /** * 上锁逻辑 */
    public synchronized void lock() throws InterruptedException { 
   
        Thread thread = Thread.currentThread();
        // 上锁了 并且 如果是同一个线程则放行,否则其它线程需要进入where循环进行等待
        while (isLocked && lockedBy != thread) { 
    
            wait();
        }
        isLocked = true; // 第一次进入就进行上锁
        lockedCount++; // 上锁次数计数
        lockedBy = thread; // 当前阻塞的线程
    }

    /** * 释放锁逻辑 */
    public synchronized void unlock() { 
   
        if (Thread.currentThread() == this.lockedBy) { 
   
            lockedCount--; // 将上锁次数减一
            if (lockedCount == 0) { 
   // 当计数为0,说明所有线程都释放了锁
                isLocked = false; // 真正的将释放了所有锁
                notify();
            }
        }
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【幅频均衡带通滤波器】基于FPGA的幅频均衡带通滤波器的设计[通俗易懂]

    【幅频均衡带通滤波器】基于FPGA的幅频均衡带通滤波器的设计[通俗易懂]1.软件版本matlab2013b,quartusii121.2.本算法理论知识带通滤波器在数字幅频均衡功率放大器中一个重要的组成部分,在介绍带通滤波器之前,我们首先来详细介绍一下数字幅频均衡功率放大器。本系统要求的指标为:本题要求在输入电压有效值为5mV的条件下,放大倍数达到400倍。而且20Hz到20kHz衰减不能超过1dB。-1dB转化为信号幅值变化为11%,可以说指标要求很高。我们可以选择使用PGA或AD620实现这一指标。整个…

    2022年9月3日
    3
  • Linux安装JDK

    Linux安装JDKLinux安装JDK

    2022年4月22日
    36
  • Java日志管理最佳实践「建议收藏」

    原文出处:http://www.ibm.com/developerworks/cn/java/j-lo-practicelog/。感谢原作者,感谢ibm网站,里面有好多的精华帖。日志记录是应用程序运行中必不可少的一部分。具有良好格式和完备信息的日志记录可以在程序出现问题时帮助开发人员迅速地定位错误的根源。对于开发人员来说,在程序中使用日志API记录日志并不复杂,不过遵循

    2022年4月11日
    39
  • mysql navicat 15 激活码【2021免费激活】

    (mysql navicat 15 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~1S…

    2022年3月27日
    333
  • harbor搭建详解(仓库阁楼搭建效果图)

    一、Harbor介绍Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署私有环境内的Registry也是非常必要的。Harbor是由VMware公司开源的企业级的DockerRegistry管理项目,它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能二、环境准备Harbo…

    2022年4月18日
    48
  • Pytest(2)使用和调用方法

    Pytest(2)使用和调用方法Pytest执行用例规则Pytest在命令行中支持多种方式来运行和选择测试用例1.对某个目录下所有的用例pytest2.对模块中进行测试pytesttest_mod.py3.对文件夹进行

    2022年7月30日
    3

发表回复

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

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