AQS之公平锁和非公平锁(二)

一、概念

注意:因为ReentrantLock 类可以实现公平锁和非公平锁,所以本文的讲解以该类为主。

1.1 公平锁

​ 多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。

1.2 非公平锁

​ 多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。在这个过程中,会和队列中的线程竞争,得到锁的顺序并不一定是先到先得。

1.3 ReentrantLock 类

​ ReentrantLock是一个可重入且独占式的锁,并且同时实现了公平锁和非公平锁,所以本文的讲解以该类为主。

1.3.1 Sync

​ Sync是RenntrantLock类的一个内部抽象类,官方解释为是一个帮助类。该类继承了AQS,所以具备AQS的大部分属性和方法,同时又重写了一些必要方法:tryRelease(),isHeldExclusively(),也就是说继承该类的类都具有该方法。同时该类有新加一些自己的方法,供具体的实现类使用:nonfairTryAcquire(),newCondition()。nonfairTryAcquire()是为了非公平锁模式下竞争锁,newCondition(),最终是为了创建条件队列。

1.3.2 NonfairSync

NonfairSync继承了Sync,是一个实现类,重要的方法有:lock(),tryAcquire(int acquires)

1.3.3 FairSync

FairSync继承了Sync,是一个实现类,重要的方法有:lock(),tryAcquire(int acquires)

总结:公平锁和非公平锁在概念上的区分:是否优先进入队列。优先进入队列的线程是公平锁,优先抢占资源的是非公平锁。

二、公平锁和非公平锁重要方法

2.1 lock

​ 使用RenntrantLock构造函数可以构建公平锁和非公平锁,两者区别主要体现在lock方法中,具体有两处,构造方法如下:

//默认非公平锁
public ReentrantLock() {sync = new NonfairSync();}
//传入true,可以构建公平锁
public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}

​ ReentrantLock的获取锁方法的路径:lock()->acquire(),其中acquire()方法可以参考AQS之理论知识(一)中的讲解,两者的区别是lock方法以及不同实现类重写的tryAcquire()。

2.2.1 NonfairSync 的lock

final void lock() {//区别一:非公平锁竞争锁资源会先去竞争锁,而公平锁只会在锁状态为0时才会竞争锁if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}

​ 调用NonfairSync 的lock,直接竞争锁,成功的话直接返回。失败的话,执行acquire(),因为AQS是模块方法,所以NonfairSync 需要重写tryAcquire(),在这个方法中当锁状态为0时直接竞争锁,无需查看队列是否有线程。

2.2.2 FairSync的lock

final void lock() {acquire(1);}
 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;}

​ 调用FairSync的lock,直接执行acquire(),因为AQS是模块方法,所以FairSync需要重写tryAcquire(),在这个方法中当锁状态为0时直接竞争锁,需要查看队列是否有线程,有线程的话将新线程添加到队列中,其他业务和非公平锁一致。

​ 总结:区别一:非公平锁竞争锁资源会先去竞争锁,而公平锁只会在锁状态为0时才会竞争锁;

​ 区别二:公平锁查看队列里面是否有节点,有的话,加入队列,没有的话直接区抢锁;而非公平锁则是直接抢锁。

2.2 unlock

public void unlock() {sync.release(1);}public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;}

​ RenntrantLock的解锁调用的是AQS的release(),而解锁调用的tryRelease(arg)是两者共用的。所以解锁的步骤依然是两大步骤:

​ 2.2.1 更改锁状态,如果锁被完全释放,同时将独占锁绑定的线程清空;

​ 2.2.2 唤醒队列的节点绑定的线程。

2.3 await

​ 因为await方法最终调用的是Condition中的方法,所以AQS中await方法无法重写,都是公用AQS现成的方法。具体参考AQS之理论知识(一)对此的描述。

2.4 signal

​ 因为signal方法最终调用的是Condition中的方法,所以AQS中signal方法无法重写,都是公用AQS现成的方法。具体参考AQS之理论知识(一)对此的描述。

三、总结

​ 3.1 公平锁和非公平锁在概念上的区分:是否优先进入队列。优先进入队列的线程是公平锁,优先抢占资源的是非公平锁;

​ 3.2公平锁和非公平锁的在ReentrantLock实现上的区别:

​ 区别一:非公平锁竞争锁资源会先去竞争锁,而公平锁只会在锁状态为0时才会竞争锁;

​ 区别二:公平锁查看队列里面是否有节点,有的话,加入队列,没有的话直接区抢锁;而非公平锁则是直接抢锁。

AQS之公平锁和非公平锁相关推荐

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

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

  2. java中ReentrantLock实现,公平锁和非公平锁,AQS并发队列,

    一般在java中,遇到并发的时候,我们很多时候可能会使用synchronized关键字来实现锁,但是synchronized关键字有一定的缺陷(比如无法实现类似读锁.非公平),而Lock可以实现.在j ...

  3. aqs原理初探以及公平锁和非公平锁实现

    深入理解AQS 一,AQS 1,ReentrantLock 2,CAS 3,AbstractQueuedSynchronizer 3.1,FairSync 3.2,NofairSync 3.3,AQS ...

  4. AQS中的公平锁和非公平锁

    正文 公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁. 优点:所有的线程都能得到资源,不会饿死在队列中. 缺点:吞吐量会下降很多,队列里面除了第一个 ...

  5. AQS中公平锁和非公平锁区别,你知道么

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/weixin_43823391/ article/details/114259418 一.概念 注意:因为ReentrantLo ...

  6. java公平所与非公平所_一张图读懂Java非公平锁与公平锁

    前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820- 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq了,但是怀旧一下,欢迎加入六脉神剑Ja ...

  7. ReentrantLock与公平锁、非公平锁实现

    前言  最近开始读JDK源码,所有心得准备总结成一个专栏,JDK Analysis系列的第一篇,就从万众瞩目的ReentrantLock开始吧,而谈到ReentrantLock,就不得不说AQS,它是 ...

  8. kali锁屏后无法唤醒_面试官:说一下公平锁和非公平锁的区别?

    前言 上次我们提到了乐观锁和悲观锁,那我们知道锁的类型还有很多种,我们今天简单聊一下,公平锁和非公平锁两口子,以及他们在我们代码中的实践. 正文 开始聊之前,我先大概说一下他们两者的定义,帮大家回顾或 ...

  9. reentrantlock非公平锁不会随机挂起线程?_【原创】Java并发编程系列16 | 公平锁与非公平锁...

    本文为何适原创并发编程系列第 16 篇,文末有本系列文章汇总. 上一篇提到重入锁 ReentrantLock 支持两种锁,公平锁与非公平锁.那么这篇文章就来介绍一下公平锁与非公平锁. 为什么需要公平锁 ...

最新文章

  1. php-fpm配置详解
  2. 用Python爬网页需要了解什么背景知识
  3. 【技术综述】人脸妆造迁移核心技术总结
  4. hdu 1863(最小生成树kruskal)
  5. 【51Nod-1100】 斜率最大(贪心)☆双排序
  6. 一文带你认识队列数据结构
  7. 快读快写:读入输出优化
  8. mysql analyze_mysql analyze和optimize
  9. 将Exr多个图片合成视频
  10. 微x怎么设置主题_苹果x前置呼吸灯怎么设置
  11. 化繁为简——分解复杂的SQL语句
  12. 电脑换个地方用有线就上不了网的问题
  13. PIC16F648A-E/SS PIC16 8位 微控制器,7KB(4Kx14)
  14. 100本书的100句话,句句直刺心底!
  15. Python unittest利用discover获取指定目录或多级目录下的测试用例
  16. el-select和el-tree树形结构下拉单选和多选
  17. 液晶屏MIPI接口与LVDS接口区别(总结)
  18. 如何将一个软件程序设置为开机启动项(win10系统)
  19. 经验之谈-关于实际项目微前端优化
  20. oracle12c安装卡住_oracle 12c 安装指南(各种问题总结)

热门文章

  1. 指针--字符串倒序输出
  2. C++ 常用容器成员函数用法总结
  3. 许多人在恋爱时,根本不晓得自己结婚的标准
  4. Linux用户与用户组配置文件详解
  5. Spring Boot 面试,一个问题就干趴下了。
  6. 阿里云物联网平台开发学习(一)
  7. 用SDF文件模拟激光雷达
  8. 第五届传智杯【初赛】- E-梅莉的市场经济学
  9. git本地服务器搭建-windows环境
  10. VUE打包图片加载失败问题