• ReentrantLock


    看了下J.U.C并发包下的ReentrantLock源码,费了不少劲,做个小总结吧,尽量用通俗易懂的语言描述,配上一些图说明。

    ReentrantLock介绍

    ReentrantLock是基于AbstractQueuedSynchronizer(AQS框架)设计的,类里面有一个私有sync成员属性,其类型为AbstractQueuedSynchronizer;

    那么什么是AQS框架呢?AQS是由大神Doug Lea设计的,他写了一篇论文叫《The java.util.concurrent Synchronizer Framework 》,里面详细描述了AQS的设计思想,想看中文翻译的,可以去并发编程网里阅读,链接

    我这里简要说明下,AQS主要是维护了一个int类型的state属性,一个非阻塞、先进先出的线程等待队列;其中state是用volatile修饰的,保证线程之间的可见性,队列的入队和出对操作都是无锁操作,基于自旋锁和CAS实现;另外AQS分为两种模式:独占模式和共享模式,本文讨论的ReentrantLock,主要涉及AQS的独占模式

    回过头来说ReentrantLock,其内部有三个内部类Sync、NonfairSync和FairSync,其中NonfairSync和FairSync继承SyncSync继承AbstractQueuedSynchronizer,这三个内部类主要是为了实现父类AbstractQueuedSynchronizer中未实现的tryRelease(int)和tryAcquire(int)方法;

    其实ReentrantLock类本身并没有实现什么新功能,仔细观察其下面的方法,发现都是通过调用sync的方法去实现的,如下所示:

        //省略前面部分...
        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);
        }
        public Condition newCondition() {
            return sync.newCondition();
        }
        public boolean isHeldByCurrentThread() {
            return sync.isHeldExclusively();
        }
        //省略后面部分...

    源码分析

    先看一下我们平时都是怎样使用ReentrantLock的,如下代码:

            ReentrantLock lock = new ReentrantLock();
            lock.lock();
    
            try {
                // do something
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

    这里的ReentrantLock是一个非公平独占锁,其保证do something在同一时刻只有一个线程能访问,当有线程正在执行do something里的代码时,其它线程将会等待。

    那么,我们就先从lock方法开始,分析ReentrantLock是如何实现非公平独占锁的;

    ReentrantLock的lock方法调用的是synclock方法,而sync是在构造方法里初始化的,由于我们未传入参数,默认为NonfairSync类型;

    lock方法,调用synclock方法:

        public void lock() {
            sync.lock();
        }

    无参构造方法,默认为非公平锁:

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

    按照执行步骤,转到NonfairSync的lock方法:

    接着调用:

  • 相关阅读:
    vue-d2admin-axios异步请求登录,先对比一下Jquery ajax, Axios, Fetch区别
    beego 前后端分离登录验证
    Beego没gin配置静态页面方便
    beego-vue URL重定向(beego和vue前后端分离开发,beego承载vue前端分离页面部署)
    Go程序员面试算法宝典-读后感2-链表
    Go程序员面试算法宝典-读后感1
    bee api new
    golang-结构体的使用
    golang-笔记2
    golang-笔记1
  • 原文地址:https://www.cnblogs.com/chenpi/p/5607449.html
Copyright © 2020-2023  润新知