当前位置: 首页 > 编程日记 > 正文

j.u.c.locks.AbstractQueuedSynchronizer.Node

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

AQS是JUC当中最核心的部分,大部分多线程讲解,都不会详细讲AQS,AQS的源代码,要看明白还是有点困难的。但是一旦看明白了,结构还是蛮清晰的。这里我们把AQS拆开,分成几部分来讲,就会很清楚了。首先先从内部类Nde讲起

上源代码:

static final class Node {static final int CANCELLED =  1;static final int SIGNAL    = -1;static final int CONDITION = -2;static final Node SHARED = new Node();static final Node EXCLUSIVE = null;volatile int waitStatus;volatile Node prev;volatile Node next;volatile Thread thread;Node nextWaiter;final boolean isShared() {return nextWaiter == SHARED;}final Node predecessor() throws NullPointerException {Node p = prev;if (p == null)throw new NullPointerException();elsereturn p;}Node() {    // Used to establish initial head or SHARED marker}Node(Thread thread, Node mode) {     // Used by addWaiterthis.nextWaiter = mode;this.thread = thread;}Node(Thread thread, int waitStatus) { // Used by Conditionthis.waitStatus = waitStatus;this.thread = thread;}}

这个NODE类是java.util.concurrent.locks.AbstractQueuedSynchronizer的内部类。主要实现了一个链表的数据结构中的节点。先不谈这个链表是做什么的,我们先看看这个节点是怎么构造的。

首先,这个节点有四个状态 ,其中三在Node类中已经明确定义,另外一个状态为初始状态,值为0

        static final int CANCELLED =  1;static final int SIGNAL    = -1;static final int CONDITION = -2;

1 :当前节点被取消或者中断

-1:下一个节点需要被释放

-2:当前节点正处在等待队列中

0 :不属于任何一种


其次,这个节点有两种模式,其中SHARED是共享模式,EXCLUSIVE是独占模式。

        static final Node SHARED = new Node();static final Node EXCLUSIVE = null;

等一下再介绍这两个模式。先把数据结构看完。


然后是成员变量:

        volatile int waitStatus;volatile Node prev;volatile Node next;volatile Thread thread;Node nextWaiter;

volatile int waitStatus:当前节点的状态,一共四种

volatile Node prev:链表的前一个节点

volatile Node next:链表的后一个节点

volatile Thread thread:这个节点所处的线程

Node nextWaiter:这个节点等待的模式(共享模式和独占模式)


接下去的两个方法和三个构造方法非常简单,就不讲了。


问题1:这个链表是如何工作的?

用一张图表示队列的工作方式:

005645_jeuK_1859279.jpg

    1. 每个节点都拥有一个指针,知道自己的前一个节点

    2. 每个节点都有一个状态位,表示是否占用资源

    3. 每个节点都要完成自旋判断上一个节点的状态(图中while循环),才能真正的执行自己的逻辑

    4. 当逻辑执行完,会修改自己的节点的状态,放开下个节点的自旋

    5. 新插入的节点,永远在队尾


上图已经非常清楚的描述了这个队列的工作方式。这就是CLH锁的原理。其实实现锁还有几种不同的方式。(点击了解更多锁的实现原理和比较)


由于一个线程的状态不止两种,所以Node的状态实现,并没有用True/False表示。而是用了waitStatus表示。另外为了操作的方便,Node并没有使用单向链表,而是双向链表。这样操作起来会方便很多。

如下图:

005524_C5b1_1859279.jpg

  1. 每个节点都拥有一个指针,知道自己的前一个节点和后一个节点

  2. 每个节点都有一个状态位,表示是否占用资源

  3. 每个节点都要完成自旋判断上一个节点的状态(图中while循环),才能真正的执行自己的逻辑

  4. 当逻辑执行完,会修改自己的节点的状态,放开下个节点的自旋

  5. 新插入的节点,永远在队尾。队尾节点标记新插入节点

  6. 被取消或者中断的线程节点,会从链表中断开,被删除

还记得在讲LockSupport(点击查看源码)中是如何挂起和恢复一个线程的吗?Thread对象就是做这个的。

到此为止,我们的图与Node类的结构是不是已经很像了呢?


问题2:共享模式和独占模式

共享模式和独占模式是两种不同的锁定资源的方式。

最经典的举例就是对共享文件的操作。当第一个,第二个用户都请求读取文件内容时,并不会阻塞用户的读取行为,并且可以并发的读取。

但是当第三个用户请求修改的时候,就会获取一个独占锁。一旦获取了独占锁,所有共享锁的获取或者独占锁的获取都会被阻塞,一直等

到独占锁被释放才会解除阻塞。

实际在JUC中读写锁也是一个很典型的共享与独占的例子。















转载于:https://my.oschina.net/readjava/blog/282969

相关文章:

使用C#开发COM+组件

一般来说,在IT技术界以及硬件产业,技术的更新换代速度非常得惊人,而惯例是所有的新技术都会遵循向下兼容的原则,但是.NET技术不仅仅做到了这一点,.NET甚至实现了相互之间的各自调用,这一点是非常难能可贵的…

香奈儿的 AI 实验室里,发生了什么?

作者 | 库珀来源 | 数据实战派头图 | 下载于ICphotoAI 已经能够在给你播报今日天气时提供穿衣建议。相信你大多数情况下都听进去了。如果它给你提供美妆建议呢?包括香奈儿在内,越来越多的美容品牌正在将 AI 技术结合到其产品之中。可是,人工智…

VS code for python开发利器

转发点赞支持引言最近在整理python自动化测试课程的内容,发现了微软出的vs code编辑器太牛逼了,非常好用,而且轻量的不要不要的,特此记录下,有选择纠结症的朋友我强烈推荐使用ta。PS:兼容win10且兼容高分辨…

C#编码标准--命名约定和风格

命名约定和风格 1. 使用Pascal的命名规范命名类型和方法的名字。 public class SomeClass { public SomeMethod(){} } 2. 使用camel命名规范命名局部变量和方法的参数。 int number; void MyMethod(int someNumber) {} 3. 在命名接…

与AMD合并后,赛灵思与英特尔、英伟达在数据中心市场呈“三足鼎立”之势

被以350亿美元的价格收购后,全球独一家FPGA公司赛灵思归于芯片巨头AMD的麾下,正式成为AMD的一份子。如果英伟达收购ARM顺利进行,无疑将让半导体行业格局再次发生巨变。 赛灵思为什么会选择归于AMD旗下?成为AMD的一份子之后&#…

Android -- Fragment注意事项

ViewPagerFragment 让Fragment成为ViewPager的一页时,FragmentManager会一直保存管理创建好了的Fragment,即使当前不是显示的这一页,Fragment对象也不会被销毁,…

C#编码标准--编码习惯

1. 避免将多个类放在一个文件里面。 2. 一个文件应该只有一个命名空间,避免将多个命名空间放在同一个文件里面。 3. 一个文件最好不要超过500行的代码(不包括机器产生的代码)。 4. 一个方法的代码长度最好不要超过25行。 5. 避免方法中有超过…

官宣!《新程序员·开发者黄金十年》正式发布

“在互联网还不发达的时代,就是《程序员》伴我成长的。”“怀念啊,曾经《程序员》的日子。”“我是看着《程序员》长大的,大二时买了创刊号。”“这可是我们这一代人大学时候满满的回忆,也是当时寝室中传阅最多的书。”“每年的《…

java笔记(一)

2019独角兽企业重金招聘Python工程师标准>>> java数组是静态的,即数组被初始化后,其所占内存空间、数组长度是不可变的。初始化数组有静态初始化和动态初始化两种: public class ArrayTest {//以下是数组的两种静态初始化String[]…

遮罩效果的实现

很多时候我们需要用到遮罩弹出层效果&#xff0c;下面给出一个简单的遮罩demo&#xff1b; 效果演示 demo代码 注意引入jquery <html> <head> <meta charset"utf-8"> <title>遮罩</title><script srcjquery-1.8.3.min.js></s…

C#实现汉字转化为拼音

其实现的原理就是先将汉字转化成为内码&#xff0c;然后通过内码和拼音的对照来查找。 详细的代码如下所示&#xff1a; public class chs2py {private static int[] pyvaluenew int[]{-20319,-20317,-20304,-20295,-20292,-20283,-20265,-20257,-20242,-20230,-20051,-20036,…

c基础知识复习

C的发展历程 C原本是为了开发UNIX操作系统而设计的语言&#xff1b;如此说&#xff0c;应该C比UNIX更早问世&#xff0c;而事实并非如此&#xff0c;最早的UNIX是由汇编写的&#xff1b; C语言本来是美国人开发的&#xff0c;解读C的声明&#xff0c;最好还是用英语来读&#x…

训练 GPT-3,为什么原有的深度学习框架吃不消?

本文梳理了深度学习框架在支持大规模预训练模型时面临的技术挑战&#xff0c;以及当前各类框架的基本解决思路&#xff0c;帮助算法工程师对业界各类框架的分布式训练能力有更清晰的认知。作者 | 一流科技CEO袁进辉头图 | 下载于ICphoto近年来&#xff0c;深度学习被广泛应用到…

ImageMagick简单记录

一、安装 mac下的安装非常简单 brew search ImageMagick brew install xxx 安装后&#xff0c;可验证 magick logo: logo.gif identify logo.gif display logo.gif 更多安装方式参考&#xff1a;http://www.imagemagick.org/script/download.php 二、命令介绍 命令概览convert&…

低代码、RPA 和 AI,有什么区别

来源 | LowCode低码时代头图 | 下载于视觉中国在To B领域&#xff0c;低代码、RPA和AI可谓是“流量担当”&#xff0c;它们自带To B基因&#xff0c;搭载快速发展的企业服务赛道&#xff0c;在企业级IT服务这一细分市场崭露头角。以这三者为代表的前沿理念和科技引领IT产业升级…

C# 获取 IE 临时文件

大家知道&#xff0c;在我们访问一个网站的时候。系统会把这个网站上的图片&#xff0c;动画等内容全部缓存到Internet临时文件夹中。 我们可以通过 <Drives>:/Documents and Settings/<user>/Local Settings/Temporary Internet Files访问。但是可能我们都没有想…

wifidog接口文档(转)

目录(?)[-] 网关心跳协议 请求信息 回复格式 例子用户状态心跳协议 请求格式 注意 回复格式 状态码 例子跳转协议 请求格式 例子注册协议 请求格式 例子wifidog是搭建无线热点认证系统的解决方案之一&#xff0c;他比nocat更适合互联网营销思路。目前支持openwrt系统&#xff…

Oracle XQuery 过滤XML查询SQL

Oralce 支持SQL XQuery查询 一个简单示例&#xff1a; SELECT XMLQuery(for $i in /Videogame return $i/Type passing by value X RETURNING CONTENT) FROM (SELECT XMLTYPE(<Videogame><Type>Racing</Type><Name>NFS Most Wanted</Name><…

C#2.0匿名函数

C# 2.0中提供了通过delegate实现匿名函数功能&#xff0c;能有效地减少用户记代码工作&#xff0c;例如 以下为引用&#xff1a; ... button1.Click new EventHandler(button1_Click); ... void button1_Click(Object sender, EventArgs e) { // Do something, the button…

第三届北京智源大会开幕,全球最大智能模型“悟道2.0”重磅发布

6月1日&#xff0c;由北京智源人工智能研究院&#xff08;以下简称智源研究院&#xff09;主办的2021北京智源大会在北京中关村国家自主创新示范区会议中心成功开幕。 北京智源大会是智源研究院主办的年度国际性人工智能高端学术交流活动&#xff0c;定位于“AI内行顶级盛会”…

Cloneable接口和循环冗余校验算法

1 Cloneable 接口 实现该接口的类可以调用clone()方法合法地对该类实例进行按字段复制。按照惯例&#xff0c;实现此接口的类应该使用公共方法重写 Object.clone&#xff08;它是受保护的&#xff09; 2 循环冗余校验算法 循环冗余校验&#xff08;英语&#xff1a;Cyclic redu…

IOS自定义表格UITableViewCell

在UITableView中&#xff0c;自定义表格&#xff0c;最原始是继承UITableViewCell&#xff0c;然后通过写代码方式去搞&#xff0c;但是这个费事了。 1.在storyboard中 给一个ViewController的tabieview增加自定义的UITableViewCell&#xff0c;可以直接从 object Library里面选…

postfix邮件服务器搭建

项目环境&#xff1a;一台server ip:192.168.1.100 一台mail ip:192.168.1.200 一台win7 ip:192.168.1.222项目需求&#xff1a;1&#xff1a;在DNS Master上搭建DNS&#xff0c;能够解析mail.sw.com2&#xff1a;在Mail Server上部署邮件服务器&#xff0c;和webmail软件3…

从DataView中生成Excel报表的方案(C#)

正文&#xff1a; 一、首先要引用一个Excel的组件&#xff0c;我一开始是在Office XP下尝试的&#xff0c;不 成功&#xff0c;后来把XP给干掉&#xff0c;装2k&#xff0c;就成功了&#xff0c;所以这里分享的是Office 2k下 引用相关组件来实现功能的&#xff0c;在工程中引…

被Python「苦虐」的日子太惨了!

Python因为其优越的特性广泛应用于数据分析、人工智能、Web开发、后端开发、自动化测试/运维、爬虫等领域&#xff0c;也得到了很多企业的青睐。甚至连BATZJ的技术大牛&#xff0c;都无可否认Python现在对于一个程序员发展的重要性&#xff01;最近一两年&#xff0c;我身边也有…

BeanUtils威力和代价

2019独角兽企业重金招聘Python工程师标准>>> BeanUtils: 威力和代价&#xff08;转载综合&#xff09; Apache Jakarta Commons项目非常有用。我曾在许多不同的项目上或直接或间接地使用各种流行的commons组件。其中的一个强大的组件就是BeanUtils。我将说明如何使…

C# 线程无法开启窗口的原因

在 C# 里面, 主窗口拥有主线程, 主线程产生子线程监控 Socket 埠, 子线程一收到数据流就会给主线程发送一个事件, 创建一个窗口. 现在的情况是子线程能够收到数据流, 主窗口能够收到子线程发送过来的事件, 能够创建一个窗口. 这个窗口有问题: 窗口状态像死掉程序的窗口一样, 反…

给力!斩获 GitHub 14000 Star,两周创办开源公司获数百万美元融资

作者 | 伍杏玲出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;上世纪 90 年代初&#xff0c;21 岁大学生 Linus Torvalds 开源 Linux 操作系统&#xff0c;自此掀起全球开源浪潮。随后“中国 Linux 第一人”宫敏博士用手提肩背的方式将 20 盒磁带背回中国&#xff0…

root密码忘记怎么办

开机按e进入系统的紧急求援模式依次输入一下命令&#xff1a;mount -o remount&#xff0c;rw /sysrootchroot /sysrootecho "输入新密码" | passwd --stdin rootexitreboot转载于:https://blog.51cto.com/11552940/1971850

C#内容分页简单实现代码及祥解

//定义变量 int i,start,stop,t,stat,statt,pp,pagecount,pagesize; //变量初始值 stat0; statt0; start0;//开始查询的字符串位置&#xff0c;初始为0 stop0; pagesize2000;//定义每页至少显示字符串数 pagecount0; //获得当前的页数 paRequest.Params["page&qu…