java中多线程reentlock_Java多线程系列——深入重入锁ReentrantLock

本文详细介绍了Java中的可重入锁ReentrantLock,包括其可重入特性、与synchronized的对比、公平锁与非公平锁的区别,以及中断响应和限时锁申请等高级功能。通过示例代码展示了ReentrantLock的工作原理和使用场景,帮助读者深入理解Java多线程编程中的这一重要工具。

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

简述

ReentrantLock 是一个可重入的互斥(/独占)锁,又称为“独占锁”。

ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychronized,是实现锁的关键)来实现锁的获取与释放。

其可以完全替代 synchronized 关键字。JDK 5.0 早期版本,其性能远好于 synchronized,但 JDK 6.0 开始,JDK 对 synchronized 做了大量的优化,使得两者差距并不大。

“独占”,就是在同一时刻只能有一个线程获取到锁,而其它获取锁的线程只能处于同步队列中等待,只有获取锁的线程释放了锁,后继的线程才能够获取锁。

“可重入”,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。

该锁还支持获取锁时的公平和非公平性选择。“公平”是指“不同的线程获取锁的机制是公平的”,而“不公平”是指“不同的线程获取锁的机制是非公平的”。

简单实例

importjava.util.concurrent.locks.ReentrantLock;/*** Created by zhengbinMac on 2017/3/2.*/

public class ReenterLock implementsRunnable{public static ReentrantLock lock = newReentrantLock();public static int i = 0;public voidrun() {for (int j = 0;j<100000;j++) {

lock.lock();//lock.lock();

try{

i++;

}finally{

lock.unlock();//lock.unlock();

}

}

}public static void main(String[] args) throwsInterruptedException {

ReenterLock reenterLock= newReenterLock();

Thread t1= newThread(reenterLock);

Thread t2= newThread(reenterLock);

t1.start();t2.start();

t1.join();t2.join();

System.out.println(i);

}

}

与 synchronized 相比,重入锁有着显示的操作过程,何时加锁,何时释放,都在程序员的控制中。

为什么称作是“重入”?这是因为这种锁是可以反复进入的。将上面代码中注释部分去除注释,也就是连续两次获得同一把锁,两次释放同一把锁,这是允许的。

注意,获得锁次数与释放锁次数要相同,如果释放锁次数多了,会抛出 java.lang.IllegalMonitorStateException 异常;如果释放次数少了,相当于线程还持有这个锁,其他线程就无法进入临界区。

引出第一个问题:为什么 ReentrantLock 锁能够支持一个线程对资源的重复加锁?

除了简单的加锁、解锁操作,重入锁还提供了一些更高级的功能,下面结合实例进行简单介绍:

中断响应(lockInterruptibly)

对于 synchronized 来说,如果一个线程在等待锁,那么结果只有两种情况,获得这把锁继续执行,或者线程就保持等待。

而使用重入锁,提供了另一种可能,这就是线程可以被中断。也就是在等待锁的过程中,程序可以根据需要取消对锁的需求。

下面的例子中,产生了死锁,但得益于锁中断,最终解决了这个死锁:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值