6. `Java` 并发基础之`ReentrantReadLock`

前言:随着多线程程序的普及,线程同步的问题变得越来越常见。Java中提供了多种同步机制来确保线程安全,其中之一就是ReentrantLock。ReentrantLock是Java中比较常用的一种同步机制,它提供了一系列比synchronized更加灵活和可控的操作和特性。在本篇博客中,我们将深入探讨ReentrantLock的使用和原理,并与synchronized进行对比分析,让读者更好地理解和掌握线程同步机制的应用技巧。


文章目录

  • 正文
    • [`reentrantLock` 与 `synchrozined` 的区别](#reentrantLocksynchrozined 的区别)

🚀 作者简介:作为某云服务提供商的后端开发人员,我将在这里与大家简要分享一些实用的开发小技巧。在我的职业生涯中积累了丰富的经验,希望能通过这个博客与大家交流、学习和成长。技术栈:Java、PHP、Python、Vue、React


本文收录于三木的🎈 「Java探索者之路」系列专栏,这个专栏旨在引领Java开发者踏上一段真正探索Java世界的旅程。

我们将深入探讨Java编程的方方面面,从基础知识到高级技巧,从实践案例到最新趋势,帮助你成为一名卓越的Java探索者。如果有想进入Java后端领域工作的同学,这个专栏会对你有所帮助,欢迎关注起来呀

🔥「面试」这个专栏的灵感来自于许多粉丝私信,大家向我咨询有关面试的问题和建议。我深感荣幸和责任,希望通过这个专栏,能够为大家提供更多关于面试的知识、技巧和经验。我们将一起探讨面试。期待粉丝们ssp的offer喜讯。

🌼 本人也会持续的去关注AIGC以及人工智能领域的一些动向并总结到博客中,大家感兴趣的可以关注一下我的「AI」专栏

🌊 「Python爬虫」的入门学习系列,大家有兴趣的可以看一看


🌹一起学习,互三互访,顺评论区有访必回,有关必回!!!


正文

ReentrantReadLock 属于一种手动获取释放的可重入锁,也就是操作系统中用到的读锁,是Lock 的一种实现类。

Lock 接口的定义如下:

java 复制代码
public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}
  • lock/unlock普通的获取锁和释放锁方法,会阻塞直到成功.
  • tryLock尝试获取锁,立即返回,不阻塞,如果获取成功,返回true,否则返回false
  • tryLock(long time, TimeUnit unit)
    • 尝试获取锁,如果能成功则立即返回true,否则阻塞等待
    • 但等待的最长时间由指定的参数设置,在等待的同时响应中断,如果发生了中断,抛出 InterruptedException
    • 如果在等待的时间内获得了锁,返回 true,否则返回false

Lock接口的主要实现类是ReentrantLock,它的基本用法lock/unlock实现了与synchronized一样的语义,包括:

  1. 可重入,一个线程在持有一个锁的前提下,可以继续获得该锁;
  2. 可以解决竞态条件问题;
  3. 可以保证内存可见性。

ReentrantLock有两个构造方法:

java 复制代码
public ReentrantLock()
public ReentrantLock(boolean fair) // 参数fair表示是否保证公平,不指定的情况下,默认为false,表示不保证公平

所谓公平是指,等待时间最长的线程优先获得锁。保证公平会影响性能,一般也不需要,所以默认不保证,synchronized锁也是不保证公平的。

使用显式锁,一定要记得调用unlock。一般而言,应该将lock之后的代码包装到try语句内,在finally语句内释放锁。

reentrantLocksynchrozined 的区别

相比synchronized, ReentrantLock可以实现与synchronized相同的语义,而且支持以非阻塞方式获取锁,可以响应中断,可以限时,更为灵活。不过,synchronized的使用更为简单,写的代码更少,也更不容易出错。

synchronized 代表一种声明式编程思维,程序员更多的是表达一种同步声明,由Java系统负责具体实现,程序员不知道其实现细节;显式锁代表一种命令式编程思维,程序员实现所有细节。

声明式编程的好处除了简单,还在于性能,在较新版本的JVM上,ReentrantLocksynchronized的性能是接近的,但Java编译器和虚拟机可以不断优化synchronized的实现,比如自动分析synchronized的使用,对于没有锁竞争的场景,自动省略对锁获取/释放的调用。


简单总结下,能用synchronized就用synchronized,不满足要求时再考虑Reentrant-Lock

相关推荐
考虑考虑4 小时前
Jpa使用union all
java·spring boot·后端
用户3721574261354 小时前
Java 实现 Excel 与 TXT 文本高效互转
java
浮游本尊5 小时前
Java学习第22天 - 云原生与容器化
java
渣哥7 小时前
原来 Java 里线程安全集合有这么多种
java
间彧7 小时前
Spring Boot集成Spring Security完整指南
java
间彧7 小时前
Spring Secutiy基本原理及工作流程
java
Java水解8 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆11 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学11 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole11 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端