资讯专栏INFORMATION COLUMN

ReentrantLock之AQS原理与源码详解

elisa.yang / 3449人阅读

摘要:所以大家看下面的图,就是线程跑过来加锁的一个过程。好线程现在就重新尝试加锁,这时还是用操作将从变为,此时就会成功,成功之后代表加锁成功,就会将设置为。此外,还要把加锁线程设置为线程自己,同时线程自己就从等待队列中出队了。

ReentrantLock和AQS的关系 ReentrantLock使用

AbstractQueuedSynchronizer,抽象队列同步器;给大家画一个图先,看一下ReentrantLock和AQS之间的关系。

AbstractQueuedSynchronizer为ReentrantLock的静态内部类

lock()源码分析

2、默认为非公平锁

3、最终会调用AbstractQueuedSynchronizer子类NonfairSync.lock()方法;

lock()方法做了什么事呢?
首先需要知道AQS会维护两个变量state(初始值0)、exclusiveOwnerThread(初始值null),源码如下,记录线程状态与当前加锁线程

线程1跑过来调用ReentrantLock的lock()方法尝试进行加锁,这个加锁的过程,直接就是用CAS操作将state值从0变为1。
如果之前没人加过锁,那么state的值肯定是0,此时线程1就可以加锁成功。
一旦线程1加锁成功了之后,就可以设置当前加锁线程是自己。所以大家看下面的图,就是线程1跑过来加锁的一个过程。

可重入锁

state记录加锁次数,为0时释放锁

锁的互斥是如何实现的?

线程2跑过来一下看到,哎呀!state的值不是0啊?所以CAS操作将state从0变为1的过程会失败,因为state的值当前为1,说明已经有人加锁了!
接着线程2会看一下,是不是自己之前加的锁啊?当然不是了,“加锁线程”这个变量明确记录了是线程1占用了这个锁,所以线程2此时就是加锁失败。
接着,线程2会将自己放入AQS中的一个等待队列,因为自己尝试加锁失败了,此时就要将自己放入队列中来等待,等待线程1释放锁之后,自己就可以重新尝试加锁了
所以大家可以看到,AQS是如此的核心!AQS内部还有一个等待队列,专门放那些加锁失败的线程!
同样,给大家来一张图,一起感受一下:

源码
线程2进来加锁失败后,会进入等待队列;等待队列为链表



接着,线程1在执行完自己的业务逻辑代码之后,就会释放锁!他释放锁的过程非常的简单,就是将AQS内的state变量的值递减1,如果state值为0,则彻底释放锁,会将“加锁线程”变量也设置为null!
整个过程,参见下图:

释放锁源码:

LockSupport.unpark(s.thread);


接下来,会从等待队列的队头唤醒线程2重新尝试加锁。
好!线程2现在就重新尝试加锁,这时还是用CAS操作将state从0变为1,此时就会成功,成功之后代表加锁成功,就会将state设置为1。
此外,还要把“加锁线程”设置为线程2自己,同时线程2自己就从等待队列中出队了。
最后再来一张图,大家来看看这个过程。

Node存储等待线程队列

参考资料https://juejin.im/post/5c07e5...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72655.html

相关文章

  • 图解AQS原理ReentrantLock详解-公平锁

    摘要:概述前面已经讲解了关于的非公平锁模式,关于非公平锁,内部其实告诉我们谁先争抢到锁谁就先获得资源,下面就来分析一下公平锁内部是如何实现公平的如果没有看过非公平锁的先去了解下非公平锁,因为这篇文章前面不会讲太多内部结构,直接会对源码进行分析前文 概述 前面已经讲解了关于AQS的非公平锁模式,关于NonfairSync非公平锁,内部其实告诉我们谁先争抢到锁谁就先获得资源,下面就来分析一下公平...

    Taonce 评论0 收藏0
  • 图解AQS原理ReentrantLock详解-非公平锁

    摘要:内部提供了两种的实现,一种公平模式,一种是非公平模式,如果没有特别指定在构造器中,默认是非公平的模式,我们可以看一下无参的构造函数。 概述 并发编程中,ReentrantLock的使用是比较多的,包括之前讲的LinkedBlockingQueue和ArrayBlockQueue的内部都是使用的ReentrantLock,谈到它又不能的不说AQS,AQS的全称是AbstractQueue...

    Clect 评论0 收藏0
  • Java 重入锁 ReentrantLock 原理分析

    摘要:的主要功能和关键字一致,均是用于多线程的同步。而仅支持通过查询当前线程是否持有锁。由于和使用的是同一把可重入锁,所以线程可以进入方法,并再次获得锁,而不会被阻塞住。公平与非公平公平与非公平指的是线程获取锁的方式。 1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似。所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻...

    lx1036 评论0 收藏0
  • Java多线程进阶(三)—— J.U.Clocks框架:ReentrantLock

    摘要:公平策略在多个线程争用锁的情况下,公平策略倾向于将访问权授予等待时间最长的线程。使用方式的典型调用方式如下二类原理的源码非常简单,它通过内部类实现了框架,接口的实现仅仅是对的的简单封装,参见原理多线程进阶七锁框架独占功能剖析 showImg(https://segmentfault.com/img/remote/1460000016012582); 本文首发于一世流云的专栏:https...

    jasperyang 评论0 收藏0
  • JAVA并发编程-ReentrantLock原理解读

    摘要:作者毕来生微信锁状态转换分类以后帮助我们提供了线程同步机制,通过显示定义同步锁来实现对象之间的同步。等待重新尝试因为在中是用关键字声明的,故可以在线程间可见再次判断一下能否持有锁可能线程同步代码执行得比较快,已经释放了锁,不可以就返回。 作者 : 毕来生微信: 878799579 锁状态转换 showImg(https://segmentfault.com/img/remote/...

    荆兆峰 评论0 收藏0

发表评论

0条评论

elisa.yang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<