深入分析AQS实现原理

AQS基本的概念

AQS的全称是AbstractQueuedSynchronizer是一个抽象同步队列,它提供了FIFO队列,是一个用来实现同步锁以及其他涉及到同步功能的核心组件,常见的有:ReetrantLock、CountDownLatch等
AQS是一个抽象类,主要是通过继承的方式来使用,它本身没有实现任何的同步接口,仅仅是定义了同步状态的获取以及释放的方法来提供自定义的同步组件

lock与synchronized区别

Lock基于AQS封装的锁,结合CAS实现
Synchronized是基于C++虚拟机封装的

LockSupport用法

LockSupport可以挂起或者唤醒线程是UnSafe类实现的,park()方法会阻塞当前线程
unpark(Thread)恢复当前线程

package com.mayikt;

import java.util.concurrent.locks.LockSupport;

/**
 * @Description:
 * @Author: ChenYi
 * @Date: 2020/07/25 15:19
 **/

public class Test002 {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("1");
            LockSupport.park();
            System.out.println("2");
        });
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程被唤醒");
        LockSupport.unpark(thread);
    }
}

AQS核心参数

  1. Node节点 采用双向链表的形式存放正在等待的线程 Thread等待锁的线程
  2. Head头节点 等待队列的头节点
  3. Tail尾节点 等待队列的尾节点
  4. State 锁的状态 0 无锁 1获取锁 当前线程不断的重入就会+1
  5. exclusiveOwerThread 记录锁的持有

Lock锁的底层

基于aqs+cas实现的,ReentrantLock默认是非公平锁,非公平锁的效率比公平锁的效率高,默认是非公平锁
在这里插入图片描述

公平锁

类图

在这里插入图片描述
流程图
在这里插入图片描述

        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;
        }

非公平锁

类图

在这里插入图片描述
流程图
在这里插入图片描述

  final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

AQS中为什么头结点是为空的

头结点可以简单理解就是可以不用参加排队,表示已经获取到锁的线程,已经在aqs类中已经记录绑定获取到锁的线程,所以head结点直接设置为null,防止浪费空间内存。

参考:蚂蚁课堂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值