AbstractQueuedSynchronizer的衍生品ReentrantLock(七)- 不响应中断的独占锁

1、ReentrantLock基本介绍

ReentrantLock的底层是借助AbstractQueuedSynchronizer实现,所以其数据结构依附于AQS的数据结构,关于AQS的数据结构,在该系列中已经介绍过,不再累赘。ReentrantLock是独占锁,本身也只是实现了AQS中关于独占锁的功能。而AQS中的独占锁分为不响应中断的独占锁和响应中断的独占锁。也就是纵观ReentrantLock,它的功能应该是:
(1). 非公平的不响应中断的独占锁
(2). 公平的响应中断的独占锁
(3). 公平的不响应中断的独占锁
(4). 公平的响应中断的独占锁
那么在本篇博客中,LZ主要阐述的是前2条,那就是:
(1). 非公平的不响应中断的独占锁
(2). 公平的响应中断的独占锁
2、ReentrantLock源码分析
2.1 类的继承关系

说明:ReentrantLock实现了Lock接口,Lock接口中定义了lock与unlock相关操作,并且还存在newCondition方法,表示生成一个条件。

2.2 类的内部关系

说明:ReentrantLock类内部总共存在Sync、NonfairSync、FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQueuedSynchronizer抽象类。ReentrantLock还提供了公平锁和非公平锁的选择,构造方法接受一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。公平锁与非公平锁的区别在于公平锁的锁获取是有顺序的。但是公平锁的效率往往没有非公平锁的效率高,在许多线程访问的情况下,公平锁表现出较低的吞吐量。实质上,公平锁和非公平锁的重要区别在于try方法的实现上。之后在后面的分析中,你会明白这一点。

2.3 关于Sync类

Sync有2个实现类,分别是NonfairSync和FairSync。
在这边文章中,我们主要分析NonfairSync。

请注意我们的调用栈,这里我再次重复一下调用栈图:

当你使用的是ReentrantLock的非公平模式获取锁时,调用栈就如同上面那样。从lock方法的源码可知,每一次都尝试获取锁,而并不会按照公平等待的原则进行等待,让等待时间最久的线程获得锁。

2.4 关于ReentrantLock类的委托调用

ReentrantLock类的sync非常重要,对ReentrantLock类的操作大部分都直接转化为对Sync和AQS类的操作。

2.5 ReentrantLock类的构造函数

可以看到默认是采用的非公平策略获取锁。也可以传递参数确定采用公平策略或者是非公平策略,参数为true表示公平策略,否则,采用非公平策略。通过分析ReentrantLock的源码,可知对其操作都转化为对Sync对象的操作,由于Sync继承了AQS,所以基本上都可以转化为对AQS的操作。如将ReentrantLock的lock函数转化为对Sync的lock函数的调用,而具体会根据采用的策略(如公平策略或者非公平策略)的不同而调用到Sync的不同子类。所以可知,在ReentrantLock的背后,是AQS对其服务提供了支持,由于之前我们分析AQS的核心源码,遂不再累赘。下面还是通过例子来更进一步分析源码。
3、ReentrantLock对外暴露的API
请看下面的ReentrantLock对外暴露的API:
    //不响应中断的:非公平独占锁或者公平独占锁
    public void lock() {
        sync.lock();
    }

    //响应中断的:非公平独占锁或者公平独占锁
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    //不响应中断的:非公平独占锁
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }

    //响应中断的带有超时机制的:非公平独占锁或者公平独占锁
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

    //释放锁
    public void unlock() {
        sync.release(1);
    }

    //创建一个Condition
    public Condition newCondition() {
        return sync.newCondition();
    }

    //获取当前独占锁的线程持有的state的数值
    public int getHoldCount() {
        return sync.getHoldCount();
    }

    //判断锁是否被当前线程持有
    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }

    //判断锁是否被线程持有
    public boolean isLocked() {
        return sync.isLocked();
    }

    //判断是否是公平锁
    public final boolean isFair() {
        return sync instanceof FairSync;
    }

    //获取当前持有锁的线程
    protected Thread getOwner() {
        return sync.getOwner();
    }

    //当前“等待锁的线程队列CLH”中是否有节点
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    //判断给定线程是否在当前“等待锁的线程队列CLH”中
    public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }

    //获取当前“等待锁的线程队列CLH”的总长度
    public final int getQueueLength() {
        return sync.getQueueLength();
    }

    //获取当前“等待锁的线程队列CLH”中所有等待的线程
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }

    //判断在当前“等待锁的线程队列CLH”中是否有线程等待的原因是掌握在给定的Condition手中
    public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    //获取在当前“等待锁的线程队列CLH”中线程等待的原因是掌握在给定的Condition手中的等待线程长度
    public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    //获取在当前“等待锁的线程队列CLH”中线程等待的原因是掌握在给定的Condition手中的所有等待线程
    protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }



参考文献:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值