【Java并发】重入锁ReentrankLock解析

本文详细解析了Java并发编程中的重入锁ReentrantLock,包括为何需要重入锁、重入锁的类型、ReentrantLock如何实现重入以及公平锁与不公平锁的原理和优缺点。通过学习,读者将更好地理解ReentrantLock的工作机制及其在多线程场景中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处https://blog.youkuaiyun.com/Fury97/article/details/81367900

 

目录

重入锁

为什么需要重入锁

重入锁有哪些

ReentrankLock如何实现重入

公平锁与不公平锁

ReentrankLock中公平锁的实现方法

公平锁和非公平锁的优缺点


重入锁

顾名思义,就是可以支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。


 

为什么需要重入锁

使用重入锁,可以在当一个线程获取对象A的锁之后,这个线程可以再次获取对象A上的锁。

假设某一同步方法是递归方法,那么就会不停的对此对象加锁,如果不使用重入锁,会导致线程1本身获取了对象A的锁,再获取锁时被阻塞住。

 

重入锁有哪些

我们常见的synchronized就是重入锁,而第二个重入锁ReentrankLock就是我们今天的主题。


 

ReentrankLock如何实现重入

首先明确概念:重入是指任意线程在获取到锁之后能够再次获取该锁而不会被阻塞。

实现该特性需要解决两个问题:

  1. 锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则成功获取。
  2. 线程重复n次获取了锁,那么就要释放n次锁,否则其他线程还是无法获取该锁。ReentrankLock通过要求每次获取锁时进行计数自增,当锁被释放时,计数自减,计数为0时表示锁成功释放。所以前(n-1)次tryRelease()方法都是返回false,只有最后一次才返回true。

 

公平锁与不公平锁

公平锁:对于每一个线程来说,获取锁的顺序取决于线程提交请求的先后顺序。也就是FIFO,排队领锁,先来先得。

不公平锁:随缘。

我们常见的synchronized是不公平锁,所以使用synchronized有可能会出现某线程永远得不到锁而一直被阻塞。

ReentrankLock给我们提供了一个构造函数,我们可以通过构造函数来控制锁是否是公平的。

 

ReentrankLock中公平锁的实现方法

在同步队列中添加对“当前节点是否有前驱节点的判断”。

同步队列是一个队列,每一个获取锁失败的线程会成为队列中的一个节点,当持有锁的线程释放锁时会发出信号,让后面的节点的线程申请锁。

所以当前节点如果有前驱节点,即说明有比它来的更早的线程在前面,因此需要等待前驱节点中的线程获取并释放锁后,才能继续申请锁。

 

公平锁和非公平锁的优缺点

  • 公平锁没有非公平锁效率高,因为在非公平锁中经常会出现刚释放锁的线程再次获取了锁,而公平锁中线程需要不停切换。
  • 公平锁可以减少“饥饿”发生的概率,因为它总是保证来的最早的线程获得锁,而非公平锁不能保证。

 

参考资料:《Java并发编程的艺术》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值