上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的。它包含了state变量、加锁线程、等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题。

 1   /**
2 * Creates an instance of {@code ReentrantLock}.
3 * This is equivalent to using {@code ReentrantLock(false)}.
4 */
5 public ReentrantLock() {
6 sync = new NonfairSync();
7 }
8
9 /**
10 * Creates an instance of {@code ReentrantLock} with the
11 * given fairness policy.
12 *
13 * @param fair {@code true} if this lock should use a fair ordering policy
14 */
15 public ReentrantLock(boolean fair) {
16 sync = fair ? new FairSync() : new NonfairSync();
17 }
ReentrantLock有两个构造参数,一个有参,一个无参,默认的无参相当于有参数的false。
 1      /**
2 * Performs non-fair tryLock. tryAcquire is implemented in
3 * subclasses, but both need nonfair try for trylock method.
4 */
5 final boolean nonfairTryAcquire(int acquires) {
6 final Thread current = Thread.currentThread();
7 int c = getState();
8 if (c == 0) {
9 if (compareAndSetState(0, acquires)) {
10 setExclusiveOwnerThread(current);
11 return true;
12 }
13 }
14 else if (current == getExclusiveOwnerThread()) {
15 int nextc = c + acquires;
16 if (nextc < 0) // overflow
17 throw new Error("Maximum lock count exceeded");
18 setState(nextc);
19 return true;
20 }
21 return false;
22 }

如果为参数为false为非公平锁,非公平锁获取锁的方式为如果当前没有线程占有锁,当前线程直接通过cas指令占有锁,管他等待队列,就算自己排在队尾也是这样

 1        /**
2 * Fair version of tryAcquire. Don't grant access unless
3 * recursive call or no waiters or is first.
4 */
5 protected final boolean tryAcquire(int acquires) {
6 final Thread current = Thread.currentThread();
7 int c = getState();
8 if (c == 0) {
9 if (!hasQueuedPredecessors() &&
10 compareAndSetState(0, acquires)) {
11 setExclusiveOwnerThread(current);
12 return true;
13 }
14 }
15 else if (current == getExclusiveOwnerThread()) {
16 int nextc = c + acquires;
17 if (nextc < 0)
18 throw new Error("Maximum lock count exceeded");
19 setState(nextc);
20 return true;
21 }
22 return false;
23 }
 1 public final boolean hasQueuedPredecessors() {
2 // The correctness of this depends on head being initialized
3 // before tail and on head.next being accurate if the current
4 // thread is first in queue.
5 Node t = tail; // Read fields in reverse initialization order
6 Node h = head;
7 Node s;
8 return h != t &&
9 ((s = h.next) == null || s.thread != Thread.currentThread());
10 }

如果为参数为true为公平锁,公平锁获取锁的方式为如果当前线程是等待队列的第一个或者等待队列为空或为当前占有线程,则通过cas指令设置state为1或增加。公平锁加锁的线程全部是按照先来后到的顺序,依次进入等待队列中排队的,不会盲目的胡乱抢占加锁。

 

Java多线程--公平锁与非公平锁的更多相关文章

  1. “全栈2019”Java多线程第二十八章:公平锁与非公平锁详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  2. java多线程20 : ReentrantLock中的方法 ,公平锁和非公平锁

    公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得 ...

  3. java并发库 Lock 公平锁和非公平锁

    jdk1.5并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,关于两者区别,java并发编程实践里面有解释 公平锁:   Threads acquir ...

  4. Java中的公平锁和非公平锁实现详解

    前言 Java语言中有许多原生线程安全的数据结构,比如ArrayBlockingQueue.CopyOnWriteArrayList.LinkedBlockingQueue,它们线程安全的实现方式并非 ...

  5. Java 公平锁与非公平锁学习研究

    最近学习研究了一下Java中关于公平锁与非公平锁的底层实现原理,总结了一下. 首先呢,通过其字面意思,公平与非公平的评判标准就是付出与收获成正比(和社会中的含义差不多一个意思).放到程序中,尤其是 在 ...

  6. Java并发指南8:AQS中的公平锁与非公平锁,Condtion

    一行一行源码分析清楚 AbstractQueuedSynchronizer (二) 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer ...

  7. Java中的锁-悲观锁、乐观锁,公平锁、非公平锁,互斥锁、读写锁

    总览图 如果文中内容有错误,欢迎指出,谢谢. 悲观锁.乐观锁 悲观锁.乐观锁使用场景是针对数据库操作来说的,是一种锁机制. 悲观锁(Pessimistic Lock):顾名思义,就是很悲观,每次去拿数 ...

  8. Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  9. Java之ReentrantLock公平锁和非公平锁

    在Java的ReentrantLock构造函数中提供了两种锁:创建公平锁和非公平锁(默认).代码如下: public ReentrantLock() { sync = new NonfairSync( ...

随机推荐

  1. Docker入门教程-Linux环境安装Nginx及入门使用

    介绍 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服 ...

  2. 要点4:C的文件操作

    关于文件操作个人比较困惑的地方有两点: 关于w和wb的区别 如何定位文件的读写位置 文件格式和打开模式 c中的文件打开模式分为:文本模式和二进制模式,分别处理文本格式文件和二进制格式文件. 两个模式的 ...

  3. python连接mysql中报错1064修改方法

    Python是编程语言,MySQL是数据库,它们是两种不同的技术:要想使Python操作MySQL数据库需要使用驱动.这里选用PyMySQL驱动.下载地址: https://pypi.python.o ...

  4. 超市管理系统C语言

    登录系统 # include <stdio.h> //头文件 # include <string.h> //字符串头文件 # include <stdlib.h> ...

  5. 问题定位 | Peronca Xtrabackup 8.0近日踩坑总结 - xtrabackup 2.4和8.0区别

    目录 前言 适配过程中遇到的坑 xtrabackup 2.4和8.0区别 问题定位 坑一:MySQL 8.0 + Semi-Sync 重建问题 坑二:MySQL 8.0 + Group-Replica ...

  6. PyTorch入门-CIFAR10图像分类

    CIFAR10数据集下载 CIFAR10数据集包含10个类别,图像尺寸为 3×32×32 官方下载地址很慢,这里给一个百度云: https://pan.baidu.com/s/1oTvW8wNa-VO ...

  7. 一个简单的Android音乐播放器

    Android小白的期末作业 Android期末项目,仅用作学习使用,在线音乐部分只获取了网易云热歌榜,API来自鼻子亲了脸 传送门: GitHub 参考: anddiencn 实现功能 展示出本地的 ...

  8. vue+elementUI+vue-i18n 实现国际化

    在main.js同级建i18n文件夹,并里面建i18n.js.langs文件夹,langs文件夹下建en.js.cn.js目录如下: . ├── App.vue ├── assets │   └── ...

  9. 轻轻松松学CSS:float

    float属性,会使元素向左或向右移动,其周围的元素也会重新排列.float不仅自己飘忽不定,还对周围元素有影响,这种影响力不容小觑.他捉摸不定(浮动规律不好把握),他干涉他国内政(对周围元素有影响) ...

  10. Java程序员博客系统推荐!我调研了100来个 Java 开源博客系统,发现这 5 个最好用!

    大家好!我是 Guide 哥,Java 后端开发.一个会一点前端,喜欢烹饪的自由少年. 最近想倒腾一下博客,看了很多现成的比较成熟的开源博客系统,自己也简单从下面几个维度总结对比了一下: star数量 ...