AQS基础

作者: 步芦 | 来源:发表于2020-06-06 21:41 被阅读0次
快速一览
  • 基础定义
  • 前置知识:锁实现的原理——LockSupport
  • AQS队列管理器
  • 公平锁和非公平锁
  • 共享锁与排他锁
  • 参考文献
  • 未完待续
基础定义

AQS:AbstractQueuedSynchronizer 抽象队列同步器,是所有锁的基础。

前置知识:锁实现的原理——LockSupport

Java 的线程阻塞和唤醒是通过 Unsafe 类的 park 和 unpark 方法做到的。

public class Unsafe {
  ...
  public native void park(boolean isAbsolute, long time);
  public native void unpark(Thread t);
  ...
}

锁可以暂停线程的奥秘所在正是因为锁在底层调用了 park 方法。

线程对象 Thread 里面有一个重要的属性 parkBlocker(volatile修饰),它保存当前线程因为什么而 park。当线程被 unpark 唤醒后,这个属性会被置为 null。Unsafe.park 和 unpark 并不会帮我们设置 parkBlocker 属性,负责管理这个属性的工具类是 LockSupport,它对 Unsafe 这两个方法进行了简单的包装。

class LockSupport {
  ...
  public static void park(Object blocker) {
     Thread t = Thread.currentThread();
     setBlocker(t, blocker);
     U.park(false, 0L);
     setBlocker(t, null); // 醒来后置null
  }

  public static void unpark(Thread thread) {
     if (thread != null)
        U.unpark(thread);
     }
  }
  ...
}
AQS队列管理器

内部主要有两个部分:持有当前锁的线程和统计的次数、维持竞争失败的锁的队列。

基本原理:当前资源state=0,线程会试图获取锁,并通过CAS修改资源的state,若成功从0-1,那么当前锁的持有线程将改为当前线程(exclusiveOwnerThread原本为null)。之后其他线程竞争锁时,先看state是不是0,不是的话再看持有者是不是自己,不是的话就被记录到一个双向队列里面去(失败者队伍)。当前锁被释放后,会唤醒队首的线程,让它去获取。

公平锁和非公平锁

公平锁会在队伍有其他线程的时候进入队列等待;非公平锁会先去竞争一次,失败了才等待。(根据我看可重入锁的代码,他其实是竞争了两次,但是道理是一样的)

非公平锁就是抢夺在队首线程由park()方法返回到加锁这中间的可能性。

==Q:如果被抢走了,这时候这个线程待在队首还是重新排队呀?==

A:在队首,可以看到获取锁AcquireQueued()的方法是一个自旋的方法,如果没有获取锁就会一直尝试获取。

共享锁与排他锁

ReentrantLock的锁是排他锁,一个线程持有,其它线程都必须等待。

而 ReadWriteLock里面的读锁不是排他锁,它允许多线程同时持有读锁,这是共享锁。

共享锁和排他锁是通过 Node 类里面的 nextWaiter 字段区分的(EXCLUSIVE和SHARED)。

class AQS {
  static final Node SHARED = new Node();
  static final Node EXCLUSIVE = null;

  boolean isShared() {
    return this.nextWaiter == SHARED;
  }
}
//nextWaiter还有其他功能。在等待队列里面,它表示下一个node
参考文献

链接:https://zhuanlan.zhihu.com/p/52280869

链接:https://zhuanlan.zhihu.com/p/43423666

未完待续
  1. AQS队列维护源码
  2. 条件变量地方不明白
  3. CAS

相关文章

  • 知识梳理目录

    Java基础 Java线程池 AQS之独占锁 AQS之Condition AQS之Condition AQS之同步...

  • JAVA并发(9)——AQS介绍

    AQS概述AbstractQueuedSynchronizer(AQS)是一个提供基础框架,JDK提供的Lock是...

  • AbstractQueuedSynchronizer(AQS)中

    1.AQS概览 AbstractQueuedSynchronizer简称AQS,是JUC中实现并发的基础,Reen...

  • 并发七:AQS队列同步器实现分析

    AQS 队列同步器(AbstractQueuedSynchronizer)简称AQS,是J.U.C同步构件的基础,...

  • Java小白系列(十):CLH

    一、前言 本篇内容是为之后的内容AQS打下基础,AQS又称 Abstract Queued Synchronize...

  • AQS源码详细解读

    AQS源码详细解读 [TOC] 基础 在讲解AQS之前,有几个额外的知识需要了解。知道了这些,才能明白AQS框架中...

  • 4、AQS

    AQS 介绍 AQS 全名AbstractQueuedSynchronizer,是所有同步器的基础。它维护了一个状...

  • AQS基础

    快速一览 基础定义 前置知识:锁实现的原理——LockSupport AQS队列管理器 公平锁和非公平锁 共享锁与...

  • 队列同步器AbstractQueuedSynchronizer源

    AQS是用来构建锁或者其他同步组件的基础框架,能够实现大部分同步需求的基础,AQS基于volatile变量提供的锁...

  • Java并发——AQS源码解析

    本文通过总结源码学习,来分析了解下AQS的工作原理 AQS是juc包锁实现的基础框架,研究juc包源码之前,AQS...

网友评论

    本文标题:AQS基础

    本文链接:https://www.haomeiwen.com/subject/jjtnzhtx.html