首页 > 编程语言 >【Java 并发编程】ReentrantLock

【Java 并发编程】ReentrantLock

时间:2023-10-17 11:46:34浏览次数:43  
标签:重入 编程 Java synchronized ReentrantLock 获取 线程 公平

目录

ReentrantLock

ReentrantLock 是一个可重入的互斥锁,又被称为“独占锁”。ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。

ReentrantLock 锁在同一个时间点只能被一个线程锁持有;而可重入的意思是,ReentrantLock 锁,可以被单个线程多次获取。

ReentrantLock 分为“公平锁”和“非公平锁”,它们的区别体现在获取锁的机制上是否公平。“锁”是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock 在同一个时间点只能被一个线程获取,当某线程获取到“锁”时,其它线程就必须等待。

ReentraantLock 是通过一个 FIFO 的等待队列来管理获取该锁所有线程的:

  • 在“公平锁”的机制下,线程依次排队获取锁;

  • 而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。

公平锁和非公平锁

  • 公平锁 : 锁被释放之后,先申请的线程先得到锁。性能较差一些,因为公平锁为了保证时间上的绝对顺序,上下文切换更频繁。

  • 非公平锁:锁被释放之后,后申请的线程可能会先获取到锁,是随机或者按照其他优先级排序的。性能更好,但可能会导致某些线程永远无法获取到锁。

synchronized 和 ReentrantLock 有什么区别?

  • 两者都是可重入锁。

可重入锁 也叫递归锁,指的是线程可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果是不可重入锁的话,就会造成死锁。

JDK 提供的所有现成的 Lock 实现类,包括 synchronized 关键字锁都是可重入的。

  • 锁的实现

    • synchronized 是依赖于 JVM 实现的。

    • ReentrantLock 是 JDK 层面实现的。

      也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成。

相比 synchronized,ReentrantLock 增加了一些高级功能。主要来说主要有三点:

  • 等待可中断 : ReentrantLock 提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。

  • 可实现公平锁 : ReentrantLock 可以指定是公平锁还是非公平锁;而 synchronized 只能是非公平锁。

    所谓的公平锁就是先等待的线程先获得锁。ReentrantLock 默认情况是非公平的,可以通过 ReentrantLock 类的 ReentrantLock(boolean fair) 构造方法来指定是否是公平的。

  • 可实现选择性通知(锁可以绑定多个条件):

    • synchronized 关键字与 wait() 和 notify()/notifyAll() 方法相结合可以实现等待/通知机制。

    • ReentrantLock 类也可以实现等待/通知机制,但是需要借助于 Condition 接口与 newCondition() 方法。

标签:重入,编程,Java,synchronized,ReentrantLock,获取,线程,公平
From: https://www.cnblogs.com/larry1024/p/17769320.html

相关文章

  • 【Java 并发编程】ThreadLocal
    目录ThreadLocalThreadLocal实现线程隔离的原理ThreadLocal内存泄漏场景ThreadLocalThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类;当使用ThreadLocal来维护变量时,ThreadLocal会为每个线程创建单独的变量副本,避免因多线程操作共享变量而导致的数据不......
  • java serverlets使用数据源连接oracle数据库,并执行查询操作代码
    packagechap03;importjava.io.IOException;importjava.io.PrintWriter;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.PreparedStatement;importjava.sql.Statement;importjava.u......
  • 【Java 并发编程】LockSupport
    目录简介方法介绍阻塞和唤醒示例示例1示例2示例3阻塞对象blocker的作用和显式锁、隐式锁等待唤醒的区别简介java.util.concurrent.locks.LockSupport是一个工具类,提供了基本的线程阻塞和唤醒功能,它是创建锁和其他同步组件的基础工具,内部是基于sun.misc.Unsafe类实现的。Lo......
  • Javascript报错:Uncaught TypeError: $(...).slide is not a function
    检查网站的时候,发现网页出现一个报错,UncaughtTypeError:$(...).slideisnotafunction同时,平时没有问题的轮播图,也不轮播了。检查并解决步骤如下: 1.顺着错误提示点过去,发现就是slide函数无法运行。查看相关介绍,表示是jq文件进行了重复引用,且版本不同 如下图相关资料描......
  • 编程到底难在哪里?
    大家好,我是陶朱公Boy,一个认真生活,总想超越自己的程序员。前言知乎上有一个提问:编程到底难在哪里?↓↓↓今天,我们就这个话题,一起来做个讨论。首先调研一下,程序员的你,觉得编程难吗?如果觉得难,那到底难在哪里?有哪些地方,是你觉得自己在目前的工作或学习中,自己尚有欠缺的,需要花时......
  • Java IO 与 NIO:高效的输入输出操作探究
    引言输入输出(IO)是任何编程语言中的核心概念,而在Java中,IO操作更是应用程序成功运行的基石。随着计算机系统变得越来越复杂,对IO的要求也日益增加。在本文中,我们将探讨JavaIO和非阻塞IO(NIO)的重要性以及如何在Java中实现高效的输入输出操作。传统IO(阻塞IO)传统IO是大多数开发人员熟......
  • #关于编程小白的初次学习
    关于编程小白的学习之对前后端的理解及选择​据个人理解我把数据库比作一位数学出题者,而后端要做的就是解出这道数学题,并将这个答案交给前端。对于前端,后端给的答案终究还是太过枯燥无味,于是前端的任务就是把这个答案美化,让阅卷老师(用户)能看得更舒服,这样我们的分数才能高,当然这......
  • 这篇记录一下C#和java中的http request的测试
    1.在c#中,测试http的,一般做一个mock的httpContext,然后里面的request和response都使用mock的,这样设置好后,就可以测试controller2.在java中,因为是httpservelet这些,所以实例化测试创建mock的httprequest这些https://www.baeldung.com/java-httpservletrequest-mock@Testvoid......
  • java学习第一天-安装JDK,运行Hello.java
    卸载JDK删除java的安装目录删除JAVA_HOME删除path下关于java的目录cmd下输入java-version安装JDK华为云JDK下载链接,首先下载JDK下载对应版本安装JDK设置安装路径配置环境变量打开环境变量新建系统变量-->JAVA_HOME配置path变量,新建%JAVA_......
  • Java内部类进行回调的场合和范例
    大力:“内部类回调外部类的实现,是咋回事?”卫琴:“回调实质上是指一个外部类尽管实际上实现了某种功能,但是没有直接提供相应的接口,客户类可以通过这个外部类的内部类的接口来获得这种功能。而这个内部类本身并没有提供真正的实现,仅仅调用外部类的实现。可见,回调充分发挥了内部类具有访......