首页 > 其他分享 >AQS原理

AQS原理

时间:2022-12-06 18:11:11浏览次数:31  
标签:node Node AQS 队列 线程 原理 节点

*前置知识:

1,线程的生命周期:新建(new())--就绪(start())--运行(run())--阻塞--死亡;

线程的非运行状态: 等待,挂起,睡眠,阻塞 

正常生命周期中运行的线程,如果有同步需求,假如正在竞争一把锁,在没拿到锁时,应该被挂起。(而不是什么都不做)

2,在队列中的线程,应该处于阻塞状态,并在必要的时候被唤醒。线程的挂起和唤醒会引发线程用户态和内核态的切换。

 

一个线程管理框架的要点:

1,通用,底层通用,与上层业务解耦;

2,利用CAS,原子修改共享标记位;

3,等待队列(阻碍其它线程);

AQS(线程同步队列)基本实现原理:

 

state标记位

 

Node的结构:{

线程对象

等待状态(4个枚举值:CANCELED,SIGNAL,CONDITION,PROPAGATE)

前、后指针

}

 

入队

1,尝试获取锁(修改标记位),立即返回;tryAcquire

2,获取锁(修改标记位),愿意进入等待队列,直到获取。acquire

tryAcquire --> 上层业务逻辑;不想等待锁,自己处理;

    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

选择等待锁,调用acquire方法

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

 

addWaiter方法(),将当前线程封装成队列节点,模式为exclusive,即独占;插入到队尾;

 1     /**
 2      * Creates and enqueues node for current thread and given mode.
 3      *
 4      * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
 5      * @return the new node
 6      */
 7     private Node addWaiter(Node mode) {
 8         Node node = new Node(Thread.currentThread(), mode);
 9         // Try the fast path of enq; backup to full enq on failure
10         Node pred = tail;
11         if (pred != null) {
12             node.prev = pred;
13             if (compareAndSetTail(pred, node)) {
14                 pred.next = node;
15                 return node;
16             }
17         }
18         enq(node);
19         return node;
20     }
View Code

 

acquireQueued()方法,对队列中的线程进行挂起

LockSupport.park(this);

 挂起当前线程的条件:

 

 

 

AQS的双向队列头节点只是一个占位,并不是真正的线程节点。

curr.pre == head  判断当前节点的前置节点是不是头节点,是的话当前节点才能拿锁(当前节点位于队头)

 

*始终保证head之后只有一个节点在通过CAS在拿锁,其它线程对象都应该被挂起。 

 

 

 设计要点:

始终保证队列里只有一个线程在自旋获取锁,其它线程都是已经被挂起或者正在被挂起;

 

出队

出队则唤醒线程:

tryRelease()

release()

唤醒线程,LockSupport.unpark(thread);

同时,将全局volatile变量State的值设置为0

 

 

上面是同步队列,还有一个条件队列。

 

 

*AQS哪些地方在自旋?

可以通过看ReentrantLock源码辅助看AQS源码。

 

标签:node,Node,AQS,队列,线程,原理,节点
From: https://www.cnblogs.com/hangwei/p/16936893.html

相关文章

  • 云原生架构(一)原理概览
    系列目录云原生架构(一)原理概览云原生架构(二)环境搭建云原生架构(三)简单样例云原生架构(四)源码详解云原生架构(五)总结提高一、行业现状 云原生架构真正进入大众视野要从......
  • DNS协议—计算机网络原理
    DNS协议详解DNS协议定义DNS(DomainNameSystem)域名系统DNS协议:是一个处理IP地址与域名之间映射的网络协议,做用于应用层DNS域名结构因为用户访问别的主机时,如果一......
  • Redis原理 - 对象的数据结构(SDS、Inset、Dict、ZipList、QuickList、SkipList、RedisO
    Redis数据结构1.SDSRedis是用C语言写的,但是对于Redis的字符串,却不是C语言中的字符串(即以空字符’\0’结尾的字符数组),它是自己构建了一种名为简单动态字符串(sim......
  • 计算机组成原理(day1)
    1.二进制转换小数部分采用拼凑法(按下表)2.BCD码目的:方便机器语言与十进制快速转换2.18421码六个冗余表示十进制,运算结果落入1010(10)~1111(15)则无定义,需补0110(6)后储存。如果......
  • <二>bind1st和bind2nd的底层实现原理
    自己实现绑定器,代码如下#include<iostream>#include<iostream>#include<vector>#include<functional>#include<algorithm>#include<ctime>usingnamespaces......
  • NOR Flash擦写和原理分析
    1.NORFLASH的简单介绍NORFLASH是很常见的一种存储芯片,数据掉电不会丢失.NORFLASH支持ExecuteOnChip,即程序可以直接在FLASH片内执行(这意味着存储在NORFLASH上......
  • Docker镜像与容器的工作原理
    提纲1、bootfs和rootfs2、镜像层和镜像3、容器层和容器4、联合文件系统​1、bootfs和rootfs一般而言,Linux的操作系统由两类文件系统组成:bootfs(bootfilesystem)和r......
  • 高速缓存的工作原理
    Cache的基本原理我们先来看一个简单的cache,处理器每次请求一个字,并且每个块由一个单独的字组成。下图展示了该简单cache在请求数据项(该数据项初始不在cache中)前后的状态。......
  • Servlet_执行原理和servlet_生命周期方法
    Servlet_执行原理:执行原理:1.当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径2.查找web.xml文件,是否有对应的<url-pattern>标签内......
  • KNN分类算法原理
    1.1概述K最近邻(k-NearestNeighbor,KNN)分类算法是最简单的机器学习算法。KNN算法的指导思想是“近朱者赤,近墨者黑”,由你的邻居来推断出你的类别。本质上,KNN算法就是用距离来......