Java可重入锁的实现原理与应用场景

 更新时间:2019年01月09日 14:30:45   作者:李灿辉  
今天小编就为大家分享一篇关于Java可重入锁的实现原理与应用场景,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

可重入锁,从字面来理解,就是可以重复进入的锁。

可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。

在JAVA环境下ReentrantLocksynchronized都是可重入锁。

synchronized是一个可重入锁。在一个类中,如果synchronized方法1调用了synchronized方法2,方法2是可以正常执行的,这说明synchronized是可重入锁。否则,在执行方法2想获取锁的时候,该锁已经在执行方法1时获取了,那么方法2将永远得不到执行。

可重入锁在什么场景使用呢?

可重入锁主要用在线程需要多次进入临界区代码时,需要使用可重入锁。具体的例子,比如上文中提到的一个synchronized方法需要调用另一个synchronized方法时。

可重入锁的实现原理是怎么样的?

加锁时,需要判断锁是否已经被获取。如果已经被获取,则判断获取锁的线程是否是当前线程。如果是当前线程,则给获取次数加1。如果不是当前线程,则需要等待。

释放锁时,需要给锁的获取次数减1,然后判断,次数是否为0了。如果次数为0了,则需要调用锁的唤醒方法,让锁上阻塞的其他线程得到执行的机会。

下面是一个用synchronized实现的例子:

public class ReentrantTest implements Runnable {
  public synchronized void get() {
    System.out.println(Thread.currentThread().getName());
    set();
  }
  public synchronized void set() {
    System.out.println(Thread.currentThread().getName());
  }
  public void run() {
    get();
  }
  public static void main(String[] args) {
    ReentrantTest rt = new ReentrantTest();
    for(;;){
      new Thread(rt).start();
    }
  }
}

整个过程没有发生死锁的情况,截取一部分输出结果如下:

Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493

set()get()同时输出了线程名称,表明即使递归使用synchronized也没有发生死锁,证明其是可重入的。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤

    SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤

    我们开发 SpringBoot 项目有时我们会需要打包成 war 包,放入外置的 Tomcat 中进行运行,或者使用工具idea直接启动,便于开发调试,本文给大家分享SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤,感兴趣的朋友一起看看吧
    2024-03-03
  • 浅谈Java基于Consul创建分布式锁

    浅谈Java基于Consul创建分布式锁

    这篇文章主要介绍了浅谈基于Consul创建分布式锁,Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置Consul是分布式的、高可用的、可横向扩展的,需要的朋友可以参考下
    2023-07-07
  • Java中使用BeanMap将对象转为Map详解

    Java中使用BeanMap将对象转为Map详解

    这篇文章主要介绍了Java中使用BeanMap将对象转为Map详解,BeanMap 是 Apache Commons BeanUtils 库中的一个类,BeanMap 可以将 Java 对象的属性作为键,属性值作为对应的值,存储在一个 Map 中,它提供了一种将 Java 对象转换为 Map 的方式,需要的朋友可以参考下
    2024-01-01
  • Springboot集成定时器和多线程异步处理操作

    Springboot集成定时器和多线程异步处理操作

    这篇文章主要介绍了Springboot集成定时器和多线程异步处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 解决Eclipse中java文件的图标变成空心J的问题

    解决Eclipse中java文件的图标变成空心J的问题

    这篇文章主要介绍了解决Eclipse中java文件的图标变成空心J的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Spring框架基于AOP实现简单日志管理步骤解析

    Spring框架基于AOP实现简单日志管理步骤解析

    这篇文章主要介绍了Spring框架基于AOP实现简单日志管理步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Springboot使用Rabbitmq的延时队列+死信队列实现消息延期消费

    Springboot使用Rabbitmq的延时队列+死信队列实现消息延期消费

    本文介绍了RabbitMQ的延时队列和死信队列,解释了它们的工作原理及其应用场景,延时队列允许消息在设定的时间后被消费,结合实际案例,展示了如何实现和使用延时队列和死信队列,感兴趣的朋友一起看看吧
    2025-01-01
  • Java 基于AQS实现自定义同步器的示例

    Java 基于AQS实现自定义同步器的示例

    这篇文章主要介绍了Java 基于AQS实现自定义同步器的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • 使用jquery 的ajax 与 Java servlet的交互代码实例

    使用jquery 的ajax 与 Java servlet的交互代码实例

    这篇文章主要介绍了使用jquery 的ajax 与 Java servlet的交互代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java源码解析HashMap的tableSizeFor函数

    Java源码解析HashMap的tableSizeFor函数

    今天小编就为大家分享一篇关于Java源码解析HashMap的tableSizeFor函数,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01

最新评论