栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ReentrantLock源码解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ReentrantLock源码解析

可重入锁

表示支持一个线程对某个资源进行重复加锁

ReentrantLock也是通过实现Lock接口并在内部聚合一个同步器来实现的,且支持公平和非公平性获取锁。所谓公平性获取锁指在同步队列中靠前的等待线程会先获得锁。

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    
    private final Sync sync;
    
    abstract static class Sync extends AbstractQueuedSynchronizer {
        final boolean nonfairTryAcquire(int acquires) {...}
        protected final boolean tryRelease(int releases) {...} 
        ...
    }
    
    static final class NonfairSync extends Sync {...}
    static final class FairSync extends Sync {...}
}
​

非公平性获取锁

每个线程都会以CAS方式更改state值以获取锁,且函数会接受一个int值表示获取锁的数量。

可以看出,如果state为0,表示没有线程持有锁,直接进行获取锁操作,若state不为0,则检查持有锁的线程是否为本线程,若是,则可以重复加锁,这就实现了可重入的功能。

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

可重入的获取锁决定了state值最大是可以超过1的,因此需要在release时进行判断,只有state值减到0时才会释放锁,若state不为0,那么tryRelease永远会返回false

protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

公平性获取锁

相较于非公平性获取锁,加入了一个判断条件!hasQueuedPredecessors(),表示只有当前线程在同步队列中没有前驱节点时才能获取锁,这就保证了公平性

protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/992959.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号