首先我们先搞明白继承关系, ReentrantLock的内部类FairSync extends Sync extends AbstractQueuedSynchronizer

  1. ReentrantLock中的内部类FairSync中lock方法,调用了AbstractQueuedSynchronizer中的acquire()方法。

    final void lock() {acquire(1);
    }
  2. acquire()方法中调用了子类FairSync中tryAcquire()方法和自身的acquireQueued()方法。
    public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}
  3. 我们先看tryAcquire(),先判断state是否为0,如果为0就执行上面提到的lock方法的前半部分,通过CAS操作将state的值从0变为1,否则判断当前线程是否为exclusiveOwnerThread,然后把state++,也就是重入锁的体现,我们注意前半部分是通过CAS来保证同步,后半部分并没有同步的体现,原因是:后半部分是线程重入,再次获得锁时才触发的操作,此时当前线程拥有锁,所以对ReentrantLock的属性操作是无需加锁的。如果tryAcquire()获取失败,则要执行addWaiter()向等待队列中添加一个独占模式的节点。

protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//公平锁和非公平锁的区别:公平锁会多一个!hasQueuedPredecessors()判断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;}

4.如果tryAcquire()返回false了,那么此时就得acquireQueued()方法。首先利用addWaiter()方法将线程封装成一个节点,加入了同步队列。在acquireQueued()方法中,如果当前节点的前驱节点是头节点,那么就调用tryAcquire()获取同步状态。

final boolean acquireQueued(final Node node, int arg) {boolean failed = true;try {boolean interrupted = false;for (;;) {final Node p = node.predecessor();if (p == head && tryAcquire(arg)) {setHead(node);p.next = null; // help GCfailed = false;return interrupted;}if (shouldParkAfterFailedAcquire(p, node) &&parkAndCheckInterrupt())interrupted = true;}} finally {if (failed)cancelAcquire(node);}}

公平锁的lock()方法走读相关推荐

  1. AQS理解之四—看看我们写的和 ReentrantLock 的公平不公平锁的区别

    AQS理解之四,看看我们写的和 ReentrantLock 的公平不公平锁的区别 首先看下ReentrantLock的lock和unlock方法. 不公平锁版本lock方法 final void lo ...

  2. 公平锁非公平锁的实际使用_理解ReentrantLock的公平锁和非公平锁

    学习AQS的时候,了解到AQS依赖于内部的FIFO同步队列来完成同步状态的管理,当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成一个Node对象并将其加入到同步队列,同时会阻塞当 ...

  3. 24-讲一讲公平锁和非公平锁,为什么要“非公平”?

    什么是公平和非公平 首先,我们来看下什么是公平锁和非公平锁,公平锁指的是按照线程请求的顺序,来分配锁:而非公平锁指的是不完全按照请求的顺序,在一定情况下,可以允许插队.但需要注意这里的非公平并不是指完 ...

  4. java并发锁有哪些,Java并发编程-公平锁与非公平锁

    写这个文章的时候让我想起了让子弹飞的一个台词 公平,公平,还是tmd公平! 什么是公平和非公平 首先,我们来看下什么是公平锁和非公平锁. 公平锁指的是按照线程请求的顺序,来分配锁: 非公平锁指的是不完 ...

  5. Java多线程学习十五:公平锁和非公平锁,为什么要“非公平”?

    什么是公平和非公平 公平锁 指的是按照线程请求的顺序,来分配锁: 非公平锁 指的是不完全按照请求的顺序,在一定情况下,可以允许插队.但需要注意这里的非公平并不是指完全的随机,不是说线程可以任意插队,而 ...

  6. 既然有公平锁,为什么还要有非公平锁

    这是我2021年的第7篇原创文章,原汁原味的技术之路尽在Jerrycodes 写这个文章的时候让我想起了让子弹飞的一个台词 公平,公平,还是tmd公平! 什么是公平和非公平 公平的场景 不公平的场景 ...

  7. 公平锁和非公平锁介绍,为什么要“非公平”?

    什么是公平和非公平 公平锁指的是按照线程请求的顺序,来分配锁:而非公平锁指的是不完全按照请求的顺序,在一定情况下,可以允许插队.但需要注意这里的非公平并不是指完全的随机,不是说线程可以任意插队,而是仅 ...

  8. 闲聊AQS面试和源码解读---可重入锁、LockSupport、CAS;从ReentrantLock源码来看公平锁与非公平锁、AQS到底是怎么用CLH队列来排队的?

    AQS原理可谓是JUC面试中的重灾区之一,今天我们就来一起看看AQS到底是什么? 这里我先整理了一些JUC面试最常问的问题? 1.Synchronized 相关问题以及可重入锁 ReentrantLo ...

  9. 公平锁和非公平锁使用和解析

    公平锁和非公平锁 在多线程的学习中,发现通过显式锁对线程上锁解决了线程安全问题后,还存在会有线程插队的问题.可能刚出来的线程又马上抢到锁再次插队进入,导致后边的线程一直轮不到,最后线程饿死了的情况发生 ...

最新文章

  1. 参考别人博客,自己实现用idea运行eclipse项目--学生管理系统-
  2. DNS SOA NS区别
  3. ECMAScript 6 入门
  4. html ascii编码方式,HTML 字符集 参考手册
  5. vue数组变化视图_vue数组操作不更新视图问题(示例代码)
  6. C++学习10 static静态成员变量和静态成员函数
  7. ChaosBlade 发布对 C++ 应用混沌实验的支持
  8. 实现Ajax异步交互
  9. mysql三大范式 答案_数据库逻辑设计之三大范式通俗理解,一看就懂,书上说的太晦涩...
  10. 容器控件StackPanel控件
  11. mysql binary-mode=1_Mysql 性能调优 二 1
  12. Eclipse引用的jar有对应的工程,「Maven依存关系」中显示对应的工程
  13. [转]一个故事讲清楚NIO
  14. dataframe 如何选中某列的一行_Spark中的RDD、DataFrame和DataSet讲解
  15. Download ebook from Syngress Publishing
  16. Peer-To-Peer 综述(P2P技术综述)
  17. Android源码下载
  18. 闽南理工学院教务网络管理系统所有服务器,闽南理工学院教务管理网络系统登录入口 http://222.77.99.244:8094/jwweb/,精英高考网...
  19. 【爬虫】谷歌、必应、百度图片爬取用于深度学习
  20. deb文件的安装与卸载

热门文章

  1. Java 14 发布了,终于可以扔掉Lombok了?
  2. 手写实现RPC框架基础功能
  3. 如何有效控制 Go 线程数?
  4. Go 语言能取代 Java,成为下一个 10 年的王者吗?
  5. OS--进程间通信详解(一)
  6. 2020对于音视频行业意味着什么?
  7. Hadoop之DataNode工作机制
  8. 腾讯计费全面开放,为你而来!
  9. ffmpeg源码学习之time_base
  10. ngx_event_expire_timers