可重入锁又称递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象必须是同一对象或者class),

不会因为之前已经获取过还没实方而发生阻塞。即同一线程可执行多个持有同一个锁的方法。

先来一段代码:

public class ReentrantSynchronized {
public synchronized void firstIPhoneByElectric() {
System.out.println("第一部iphone充电..." + Thread.currentThread().getName());
secondIPhoneByElectric();
} public synchronized void secondIPhoneByElectric() {
System.out.println("第二部iphone充电..." + Thread.currentThread().getName());
} public static void main(String[] args) {
ReentrantSynchronized reentrantSynchronized = new ReentrantSynchronized();
reentrantSynchronized.firstIPhoneByElectric();
} }

就像一个多用充电线可以同时给多部iphone充电,但是不会发生任何冲突和阻塞,也就是第一部iphone可以获取充电线(锁)充电的同时还可以第二部iphone也可以获取充电线(锁)进行充电。

执行结果如下:

在上面的代码中,类中的两个方法都被内置锁synchronized修饰,给第一部手机充电的同时(firstIPhoneByElectric方法中)给第二部手机充电(调用了secondIPhoneByElectric方法)。

因为充电线时多用的(synchronized是可重入的),所以同一个人给第二部手机充电时可以直接用该多用充电线进行充电(在同一线程在调用secondIPhoneByElectric时可以直接获得

当前对象的锁,进入secondIPhoneByElectric进行操作)。

设想:该充电线是单用的(如果synchronized不是可重入的),那么给第二部手机充电时必须等到第一部手机充电完成释放充电线后才能进行(当前线程在调用secondIPhoneByElectric

之前必须将firstIPhoneByElectric获取的锁释放掉),实际上该充电线已经被第一部手机占用,且无法释放,(该对象锁被当前线程所持有,且无法释放),所以此时会出现死锁。

这是什么原理呢?

当线程尝试获取锁时,可重入锁先尝试获取并更新status值,如果status == 0表示没有其他线程在执行同步代码,则把status置为1,当前线程开始执行。如果status != 0,

则判断当前线程是否是获取到这个锁的线程,如果是的话执行status+1,且当前线程可以再次获取锁。而非可重入锁是直接去获取并尝试更新当前status的值,如果status != 0

的话会导致其获取锁失败,当前线程阻塞。

释放锁时,可重入锁同样先获取当前status的值,在当前线程是持有锁的线程的前提下。如果status-1 == 0,则表示当前线程所有重复获取锁的操作都已经执行完毕,

然后该线程才会真正释放锁。而非可重入锁则是在确定当前线程是持有锁的线程之后,直接将status置为0,将锁释放。

Synchronized可重入锁分析的更多相关文章

  1. Synchronized可重入锁通俗易懂的简单分析

    可重入锁概念: 当一个线程得到一个对象锁后,再次请求此对象时时可以再次得到该对象的锁的,这也证明synchronized方法/块的内部调用本类的其他synchronized方法/块时,时永远可以得到锁 ...

  2. 浅谈Java中的锁:Synchronized、重入锁、读写锁

    Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...

  3. java的synchronized可重入锁

    在java内部,同一线程在调用自己类中其他synchronized方法/块或调用父类的synchronized方法/块都不会阻碍该线程的执行,就是说同一线程对同一个对象锁是可重入的,而且同一个线程可以 ...

  4. synchronized 是可重入锁吗?为什么?

    什么是可重入锁? 关于什么是可重入锁,我们先来看一段维基百科的定义. 若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(re ...

  5. synchronized的功能拓展:重入锁(读书笔记)

     重入锁可以完全代替synchronized关键字.在JDK5.0的早期版本中,重入锁的性能远远好于synchronized,但是从JDK6.0开始.JDK在synchronized上做了大量的优化. ...

  6. synchronized关键字,Lock接口以及可重入锁ReentrantLock

    多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...

  7. Java 重入锁 ReentrantLock 原理分析

    1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生 ...

  8. ReenTrantLock可重入锁(和synchronized的区别)总结

    ReenTrantLock可重入锁(和synchronized的区别)总结 可重入性: 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也 ...

  9. ReenTrantLock可重入锁和synchronized的区别

    ReenTrantLock可重入锁和synchronized的区别 可重入性: 从名字上理解,ReenTrantLock的字面意思就是再进入的锁,其实synchronized关键字所使用的锁也是可重入 ...

随机推荐

  1. golang调用c动态库

    golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...

  2. java上传图片并压缩图片大小

    Thumbnailator 是一个优秀的图片处理的Google开源Java类库.处理效果远比Java API的好.从API提供现有的图像文件和图像对象的类中简化了处理过程,两三行代码就能够从现有图片生 ...

  3. TCP 粘包问题

    TCP 粘包,主要是因为发送端发送的两个包,TCP按照流进行发送,缓冲器满了才发送. 假如两个包都比较小的话,就会把两个包合并到一起进行发送,造成接收端接到的流无法知道这是一个包还是两个包 假如发送两 ...

  4. bat文件重命名指定路径下文件

    ren "E:\产品\Planning\C1-Planning11\C1-Planning11\target\123" 456 此命令是将文件123重命名为456 注意:456是文 ...

  5. java自定义jar包让jemeter使用

    背景:可能在做定义化的要求上,jmeter原有的jar包,已经不能满足我们,就需要自己写一个方法,以下就是写入的一个模拟post的请求,在jmeter中使用的案例 一:写代码 1.代码中的有两个包,原 ...

  6. Win732位DotNetCore部署IIS错误记录

    部署环境为:Win7专业版32位,数据库Mysql5.7.27-win32 1.先启用IIS功能 2.安装Mysql5.7.27-win32,使用解压版安装 安装步骤: mysql的解压根目录下新建m ...

  7. Linux 就该这么学 CH03 管道符、重定向和环境变量

    0 概述 1 输入输出重定向 重定向技术有5种模式: 标准覆盖输出重定向 标准追加输出重定向 错误覆盖输出重定向 错误追加输出重定向 输入重定向 输入重定向是将文件导入到命令中. 输出重定向是将输入到 ...

  8. k8s-job使用

    一.job特性 运行完成后退出,但是不会被删除,便于用户查看日志信息,了解任务完成的情况 删除job时产生的pod也会被一起删除 job中可以运行多个pod(任务执行多次),且可以并行运行缩短任务完成 ...

  9. activiti学习6:启动流程后动态获取流程图

    目录 activiti学习6:启动流程后动态获取流程图 一.绘图原理 二.根据流程定义id绘图 三.根据流程实例id绘图 3.1 基本原理 3.2 当前节点的获取 3.3 走过的节点的获取 3.4 绘 ...

  10. centos7查看防火墙状态、关闭防火墙

    查看防火墙状态: firewall-cmd --state 关闭防火墙: systemctl stop firewalld.service 禁止firewall开机启动: systemctl disa ...