上一篇文章介绍了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. IDEA的主题配置

    搞了半天的主题配色,从一些现有的主题网站上想找按照sublime中monokai进行复刻的主题,都没有找到一样的,部分的颜色还会让人看不清楚,这里分享一下自定义主题的方法,和自己配置好的一个主题吧. ...

  2. CentOS7(Linux)源码安装Redis

    介绍 项目中经常需要用到Redis做缓存数据库,可是还有小伙伴不会在Linux上安装Redis,毕竟我们开发的项目都是要在服务器上运行的,今天就来讲讲如何在CentOS7环境使用源码进行安装Redis ...

  3. Linux系统下部署项目流程

    一.系统架构 linux系统 centOS 6.9 应用服务器:Tomcat /JDK 数据库服务器:MySQL 二.连接远程工具FinalShell 1.Centos 6: 启动服务:service ...

  4. 使用 Swift Package Manager 集成依赖库

      本文首发于 Ficow Shen's Blog,原文地址: 使用 Swift Package Manager 集成依赖库.   内容概览 前言 添加依赖包 在项目中使用依赖 管理已导入的依赖 在团 ...

  5. 从零开始的SpringBoot项目 ( 七 ) 统一返回结果集Result 和 异常处理

    import java.io.Serializable; import lombok.Data; import org.springframework.http.HttpStatus; @Data p ...

  6. caoz:数据分析这点事

    http://www.wocaoseo.com/thread-53-1-1.html 先声明一下,按照传统的定义,我还真不是数据分析高手,各种关联算法,只会最简单的一种(话说不少场合还算管用):各种挖 ...

  7. android开发之当设置textview多少字后以省略号显示。限制TextView的字数

    设置多少字后以省略号显示 <TextView    android:id="@+id/tv"   android:layout_width="wrap_conten ...

  8. 记录一个基于Java的利用快排切分来实现快排TopK问题的代码模板

    使用快排切分实现快排和TopK问题的解题模板 import java.util.Arrays; public class TestDemo { public static void main(Stri ...

  9. C016:字符串倒置

    代码: #include "stdafx.h" #include <string.h> int _tmain(int argc, _TCHAR* argv[]) { c ...

  10. Ubuntu 安装配置 WordPress5.4.2

    一.安装 Apache 并配置 WordPress sudo apt-get install apache2 -y //  安装 apache2 sudo apt-get install php -y ...