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

可重入锁和不可重入锁的区别不可重入锁示例(同一个线程不可以重入上锁后的代码段)如下是一个不可重入锁的逻辑过程,会发现执行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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网站访问人数太多,怎么才能进入_网址挖掘

    网站访问人数太多,怎么才能进入_网址挖掘老规矩,先上代码:#coding=utf-8importosimportrequestsimporttimefromPILimportImagefromioimportBytesIOfromlxmlimportetree#先定义一个opener函数:defopen_mn_web(url):try:headers=…

    2022年10月28日
  • 神经网络的基本原理[通俗易懂]

    神经网络的基本原理[通俗易懂]1.神经网络1.1.神经元概述神经网络是由一个个的被称为“神经元”的基本单元构成,单个神经元的结构如下图所示:对于上述的神经元,其输入为x1x_1x1​,x2x_2x2​,x3x_3x3​以及截距+1+1+1,其输出为:hW,b(x)=f(WTx)=f(∑i=13Wixi+b)h_{\mathbf{W},b}\left(\mathbf{x}\right)=f\left(\mathbf{W}^T\mathbf{x}\right)=f\left(\sum_{i=1}^{3}W_

    2022年7月20日
  • docker离线安装部署 linux_docker官方中文文档

    docker离线安装部署 linux_docker官方中文文档linux下离线安装docker一、基础环境1、操作系统:centos7.32、docker版本:18.06.1官方下载地址(打不开可能很慢)4、官方参考文档:二、docker安装1、解压tar-xvfdocker-18.06.1-ce.tgz2、将解压出来的docker文件内容移动到/usr/bin/目录下mvdocker/*/usr/bin/3、将docker注册为servic…

    2022年9月26日
  • vs2008 sp1怎么安装_vs2008激活成功教程版

    vs2008 sp1怎么安装_vs2008激活成功教程版VS2005SP1forvista安装小记

    2022年10月5日
  • 网络流详解(流网图一般能够反映什么信息)

    network-flows,网络流,传说中的省选算法先推荐一个讲网络流思路的网站:https://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html目的首先,明确网络流是干什么的给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow)….

    2022年4月18日
  • Git安装教程(详细教程)

    Git安装教程(详细教程)Git安装教程大家好,今天我们来学习一下怎么安装git这个软件,好好看,好好学,超详细的。第一步下载git(找到自己需要的版本)第二步下载完点击安装包进入使用许可声明界面第三步点击Next进入选择安装路径界面这里我是选择装在D盘,大家如果嫌麻烦就默认安装在C盘第四步点击Next进入选择安装组件界面上图红框内的选项是默认勾选的,建议不要动。绿色框1是决定是否在桌面创建快捷方式的。绿色框2是决定在所有控制台窗口中使用TrueType字体和是否每天检查Git

    2022年5月1日

发表回复

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

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