玩转并发-ReentrantLock

本文详细探讨了ReentrantLock的重入性实现原理,公平锁与非公平锁的区别,以及ReentrantLock的源码分析。ReentrantLock通过增加重入次数来支持重入,非公平锁在释放锁后可能允许刚释放锁的线程再次获取,而公平锁则遵循FIFO原则。此外,文章还介绍了ReentrantLock的内部类Sync、FairSync和NonfairSync的实现细节。
摘要由CSDN通过智能技术生成

概述

eentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java关键字synchronized隐式支持重入性(关于synchronized可以看这篇文章),synchronized通过获取自增,释放自减的方式实现重入。与此同时,ReentrantLock还支持公平锁和非公平锁两种方式。那么,要想完完全全的弄懂ReentrantLock的话,主要也就是ReentrantLock同步语义的学习:1. 重入性的实现原理;2. 公平锁和非公平锁。

重入性的实现原理

要想支持重入性,就要解决两个问题:1. 在线程获取锁的时候,如果已经获取锁的线程是当前线程的话则直接再次获取成功;2. 由于锁会被获取n次,那么只有锁在被释放同样的n次之后,该锁才算是完全释放成功通过这篇文章,我们知道,同步组件主要是通过重写AQS的几个protected方法来表达自己的同步语义。针对第一个问题,我们来看看ReentrantLock是怎样实现的,以非公平锁为例,判断当前线程能否获得锁为例,核心方法为nonfairTryAcquire:

final boolean nonfairTryAcquire(int acquires) {
   
    final Thread current = Thread.currentThread();
    int c = getState();
    //1. 如果该锁未被任何线程占有,该锁能被当前线程获取
	if (c == 0) {
   
        if (compareAndSetState(0, acquires)) {
   
        	//设置持有锁的线程为当前线程
            setExclusiveOwnerThread(current);
            return true;
        }
    }
	//2.若被占有,检查占有线程是否是当前线程
    else if (current == getExclusiveOwnerThread()) {
   
		// 3. 再次获取,计数加一
        int nextc = c + acquires;
        if (nextc < 0) // overflow
        	//nextc小于0,说明锁可重入溢出
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

为了支持重入性,在第二步增加了处理逻辑,如果该锁已经被线程所占有了,会继续检查占有线程是否为当前线程,如果是的话,同步状态加1返回true,表示可以再次获取成功。每次重新获取都会对同步状态进行加一的操作,那么释放的时候处理思路是怎样的了?(依然还是以非公平锁为例)核心方法为tryRelease:

protected final boolean tryRelease(int releases) {
   
	//1. 同步状态减1
    int c = getState() - releases;
    //释放锁的线程必须为当前线程,否则抛出异常
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
   
		//2. 只有当同步状态为0时,锁成功被释放,返回true
        free = true;
        //设置持有锁的线程为null
        setExclusiveOwnerThread(null);
    }
	// 3. 锁未被完全释放,返回false
    setState(c);
    return free;
}
公平锁与非公平锁

ReentrantLock支持两种锁:公平锁非公平锁。何谓公平性,是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求上的绝对时间顺序,满足FIFO。ReentrantLock的构造方法无参时是构造非公平锁,源码为:

public ReentrantLock() {
   
    sync = new NonfairSync();
}

另外还提供了另外一种方式,可传入一个boolean值,true时为公平锁,false时为非公平锁,源码为:

public ReentrantLock(boolean fair) {
   
    sync = fair ? new FairSync() : new NonfairSync(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值