网站设计人员白山北京网站建设

web/2025/10/4 5:50:29/文章来源:
网站设计人员,白山北京网站建设,涿州市网站建设,如何创建网站的第一步一、前言 接着前面的分析#xff0c;接下来分析ConcurrentLinkedQueue#xff0c;ConcurerntLinkedQueue一个基于链接节点的无界线程安全队列。此队列按照 FIFO#xff08;先进先出#xff09;原则对元素进行排序。队列的头部是队列中时间最长的元素。队列的尾部 是队列中时…一、前言   接着前面的分析接下来分析ConcurrentLinkedQueueConcurerntLinkedQueue一个基于链接节点的无界线程安全队列。此队列按照 FIFO先进先出原则对元素进行排序。队列的头部是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时ConcurrentLinkedQueue是一个恰当的选择。此队列不允许使用null元素。 二、ConcurrentLinkedQueue数据结构   通过源码分析可知ConcurrentLinkedQueue的数据结构与LinkedBlockingQueue的数据结构相同都是使用的链表结构。ConcurrentLinkedQueue的数据结构如下   说明ConcurrentLinkedQueue采用的链表结构并且包含有一个头结点和一个尾结点。 三、ConcurrentLinkedQueue源码分析   3.1 类的继承关系 public class ConcurrentLinkedQueueE extends AbstractQueueEimplements QueueE, java.io.Serializable {}   说明ConcurrentLinkedQueue继承了抽象类AbstractQueueAbstractQueue定义了对队列的基本操作同时实现了Queue接口Queue定义了对队列的基本操作同时还实现了Serializable接口表示可以被序列化。   3.2 类的内部类  private static class NodeE {// 元素volatile E item;// next域volatile NodeE next;/*** Constructs a new node. Uses relaxed write because item can* only be seen after publication via casNext.*/// 构造函数Node(E item) {// 设置item的值UNSAFE.putObject(this, itemOffset, item);}// 比较并替换item值boolean casItem(E cmp, E val) {return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);}void lazySetNext(NodeE val) {// 设置next域的值并不会保证修改对其他线程立即可见UNSAFE.putOrderedObject(this, nextOffset, val);}// 比较并替换next域的值boolean casNext(NodeE cmp, NodeE val) {return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);}// Unsafe mechanics// 反射机制private static final sun.misc.Unsafe UNSAFE;// item域的偏移量private static final long itemOffset;// next域的偏移量private static final long nextOffset;static {try {UNSAFE sun.misc.Unsafe.getUnsafe();Class? k Node.class;itemOffset UNSAFE.objectFieldOffset(k.getDeclaredField(item));nextOffset UNSAFE.objectFieldOffset(k.getDeclaredField(next));} catch (Exception e) {throw new Error(e);}}} View Code   说明Node类表示链表结点用于存放元素包含item域和next域item域表示元素next域表示下一个结点其利用反射机制和CAS机制来更新item域和next域保证原子性。   3.3 类的属性   public class ConcurrentLinkedQueueE extends AbstractQueueEimplements QueueE, java.io.Serializable {// 版本序列号 private static final long serialVersionUID 196745693267521676L;// 反射机制private static final sun.misc.Unsafe UNSAFE;// head域的偏移量private static final long headOffset;// tail域的偏移量private static final long tailOffset;static {try {UNSAFE sun.misc.Unsafe.getUnsafe();Class? k ConcurrentLinkedQueue.class;headOffset UNSAFE.objectFieldOffset(k.getDeclaredField(head));tailOffset UNSAFE.objectFieldOffset(k.getDeclaredField(tail));} catch (Exception e) {throw new Error(e);}}// 头结点private transient volatile NodeE head;// 尾结点private transient volatile NodeE tail; } View Code   说明属性中包含了head域和tail域表示链表的头结点和尾结点同时ConcurrentLinkedQueue也使用了反射机制和CAS机制来更新头结点和尾结点保证原子性。   3.4 类的构造函数   1. ConcurrentLinkedQueue()型构造函数   public ConcurrentLinkedQueue() {// 初始化头结点与尾结点head tail new NodeE(null);} View Code   说明该构造函数用于创建一个最初为空的 ConcurrentLinkedQueue头结点与尾结点指向同一个结点该结点的item域为nullnext域也为null。   2. ConcurrentLinkedQueue(Collection? extends E)型构造函数   public ConcurrentLinkedQueue(Collection? extends E c) {NodeE h null, t null;for (E e : c) { // 遍历c集合// 保证元素不为空checkNotNull(e);// 新生一个结点NodeE newNode new NodeE(e);if (h null) // 头结点为null// 赋值头结点与尾结点h t newNode;else {// 直接头结点的next域t.lazySetNext(newNode);// 重新赋值头结点t newNode;}}if (h null) // 头结点为null// 新生头结点与尾结点h t new NodeE(null);// 赋值头结点head h;// 赋值尾结点tail t;} View Code   说明该构造函数用于创建一个最初包含给定 collection 元素的 ConcurrentLinkedQueue按照此 collection 迭代器的遍历顺序来添加元素。   3.5 核心函数分析   1. offer函数   public boolean offer(E e) {// 元素不为nullcheckNotNull(e);// 新生一个结点final NodeE newNode new NodeE(e);for (NodeE t tail, p t;;) { // 无限循环// q为p结点的下一个结点NodeE q p.next;if (q null) { // q结点为null// p is last nodeif (p.casNext(null, newNode)) { // 比较并进行替换p结点的next域// Successful CAS is the linearization point// for e to become an element of this queue,// and for newNode to become live.if (p ! t) // p不等于t结点不一致 // hop two nodes at a time// 比较并替换尾结点casTail(t, newNode); // Failure is OK.// 返回return true;}// Lost CAS race to another thread; re-read next}else if (p q) // p结点等于q结点// We have fallen off list. If tail is unchanged, it// will also be off-list, in which case we need to// jump to head, from which all live nodes are always// reachable. Else the new tail is a better bet.// 原来的尾结点与现在的尾结点是否相等若相等则p赋值为head否则赋值为现在的尾结点p (t ! (t tail)) ? t : head;else// Check for tail updates after two hops.// 重新赋值p结点p (p ! t t ! (t tail)) ? t : q;}} View Code   说明offer函数用于将指定元素插入此队列的尾部。下面模拟offer函数的操作队列状态的变化假设单线程添加元素连续添加10、20两个元素。   ① 若ConcurrentLinkedQueue的初始状态如上图所示即队列为空。单线程添加元素此时添加元素10则状态如下所示   ② 如上图所示添加元素10后tail没有变化还是指向之前的结点继续添加元素20则状态如下所示   ③ 如上图所示添加元素20后tail指向了最新添加的结点。   2. poll函数   public E poll() {restartFromHead:for (;;) { // 无限循环for (NodeE h head, p h, q;;) { // 保存头结点// item项E item p.item;if (item ! null p.casItem(item, null)) { // item不为null并且比较并替换item成功// Successful CAS is the linearization point// for item to be removed from this queue.if (p ! h) // p不等于h // hop two nodes at a time// 更新头结点updateHead(h, ((q p.next) ! null) ? q : p); // 返回itemreturn item;}else if ((q p.next) null) { // q结点为null// 更新头结点updateHead(h, p);return null;}else if (p q) // p等于q// 继续循环continue restartFromHead;else// p赋值为qp q;}}} View Code   说明此函数用于获取并移除此队列的头如果此队列为空则返回null。下面模拟poll函数的操作队列状态的变化假设单线程操作状态为之前offer10、20后的状态poll两次。   ① 队列初始状态如上图所示在poll操作后队列的状态如下图所示   ② 如上图可知poll操作后head改变了并且head所指向的结点的item变为了null。再进行一次poll操作队列的状态如下图所示。   ③ 如上图可知poll操作后head结点没有变化只是指示的结点的item域变成了null。   3. remove函数   public boolean remove(Object o) {// 元素为null返回if (o null) return false;NodeE pred null;for (NodeE p first(); p ! null; p succ(p)) { // 获取第一个存活的结点// 第一个存活结点的item值E item p.item;if (item ! null o.equals(item) p.casItem(item, null)) { // 找到item相等的结点并且将该结点的item设置为null// p的后继结点NodeE next succ(p);if (pred ! null next ! null) // pred不为null并且next不为null// 比较并替换next域pred.casNext(p, next);return true;}// pred赋值为ppred p;}return false;} View Code   说明此函数用于从队列中移除指定元素的单个实例如果存在。其中会调用到first函数和succ函数first函数的源码如下   NodeE first() {restartFromHead:for (;;) { // 无限循环确保成功for (NodeE h head, p h, q;;) {// p结点的item域是否为nullboolean hasItem (p.item ! null);if (hasItem || (q p.next) null) { // item不为null或者next域为null// 更新头结点updateHead(h, p);// 返回结点return hasItem ? p : null;}else if (p q) // p等于q// 继续从头结点开始continue restartFromHead;else// p赋值为qp q;}}} View Code   说明first函数用于找到链表中第一个存活的结点。succ函数源码如下   final NodeE succ(NodeE p) {// p结点的next域NodeE next p.next;// 如果next域为自身则返回头结点否则返回nextreturn (p next) ? head : next;} View Code   说明succ用于获取结点的下一个结点。如果结点的next域指向自身则返回head头结点否则返回next结点。下面模拟remove函数的操作队列状态的变化假设单线程操作状态为之前offer10、20后的状态执行remove(10)、remove(20)操作。   ① 如上图所示为ConcurrentLinkedQueue的初始状态remove(10)后的状态如下图所示   ② 如上图所示当执行remove(10)后head指向了head结点之前指向的结点的下一个结点并且head结点的item域置为null。继续执行remove(20)状态如下图所示   ③ 如上图所示执行remove(20)后head与tail指向同一个结点item域为null。   4. size函数   public int size() {// 计数int count 0;for (NodeE p first(); p ! null; p succ(p)) // 从第一个存活的结点开始往后遍历if (p.item ! null) // 结点的item域不为null// Collection.size() spec says to max outif (count Integer.MAX_VALUE) // 增加计数若达到最大值则跳出循环break;// 返回大小return count;} View Code   说明此函数用于返回ConcurrenLinkedQueue的大小从第一个存活的结点first开始往后遍历链表当结点的item域不为null时增加计数之后返回大小。 五、示例   下面通过一个示例来了解ConcurrentLinkedQueue的使用   package com.hust.grid.leesf.collections;import java.util.concurrent.ConcurrentLinkedQueue;class PutThread extends Thread {private ConcurrentLinkedQueueInteger clq;public PutThread(ConcurrentLinkedQueueInteger clq) {this.clq clq;}public void run() {for (int i 0; i 10; i) {try {System.out.println(add i);clq.add(i);Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}} }class GetThread extends Thread {private ConcurrentLinkedQueueInteger clq;public GetThread(ConcurrentLinkedQueueInteger clq) {this.clq clq;}public void run() {for (int i 0; i 10; i) {try {System.out.println(poll clq.poll());Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}} }public class ConcurrentLinkedQueueDemo {public static void main(String[] args) {ConcurrentLinkedQueueInteger clq new ConcurrentLinkedQueueInteger();PutThread p1 new PutThread(clq);GetThread g1 new GetThread(clq);p1.start();g1.start();} } View Code   运行结果某一次   add 0 poll null add 1 poll 0 add 2 poll 1 add 3 poll 2 add 4 poll 3 add 5 poll 4 poll 5 add 6 add 7 poll 6 poll 7 add 8 add 9 poll 8 View Code   说明GetThread线程不会因为ConcurrentLinkedQueue队列为空而等待而是直接返回null所以当实现队列不空时等待时则需要用户自己实现等待逻辑。 六、总结   ConcurrentLinkedQueue的源码也相对简单其实对于并发集合而言分析源码时首先理解单线程情况然后再考虑在多线程并发时的情况这样会使得分析源码容易得多ConcurrentLinkedQueue和LinkedBlockingQueue的区别还是很明显的前者在取元素时若队列为空则返回null后者会进行等待。谢谢各位园友的观看~转载于:https://www.cnblogs.com/leesf456/p/5539142.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/86623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

温州企业建站系统中国移动app免费下载

深度剖析几个经典话题,以图文的形式展现,好好看图。 目录 1. 2014互联网职场薪酬报告!你拖后腿了吗? 2. 月薪8K程序员现身说法:男人就该默默做技术! 3.项目建设 4. 2014年亿级用户下的新浪微博平台架构…

建网站的软件有哪些商业推广

Linux最危险的几个命令 Linux最危险的几个命令危险命令介绍删除文件和目录命令rmLinux 的 dd 命令mkfs 格式化硬盘分区shutdown> fileMore Linux最危险的几个命令 仅个人想法,会持续不间断更新和改进。 Linux系统中的命令最美妙也最危险。 如果几个操作系统&…

关于传媒的网站模板开发一个网站需要多少时间

1、概述 源码放在文章末尾 该项目实现了多种样式的导航按钮控件 可设置文字的左侧、右侧、顶部、底部间隔。 可设置文字对齐方式。 可设置显示倒三角、倒三角边长、倒三角位置、倒三角颜色。 可设置显示图标、图标间隔、图标尺寸、正常状态图标、悬停状态图标、选中状态图标…

一级a做爰片 网站就能看wordpress主题仿制

数据可视化的实现技术和工具比较转载于:https://www.cnblogs.com/knuzy/p/9215632.html

微信对接网站群wordpress 做值班表

想都是问题,做才是答案 什么是请求走私? HTTP请求走私是针对于服务端处理一个或者多个接收http请求序列的方式,进行绕过安全机制,实施未授权访问一种攻击手段,获取敏感信息,并直接危害其他用户。 Web 应用…

网站页面制作公司安装失败未能找到wordpress目录

如果大家看过我之前的文章,可能会有点映像,前面有提到过英国的双水龙头,有兴趣的朋友们可以点后面的直达链接查看:为什么在英国留学会掉头发?怎么办?英国的自来水(冷水)可以直接喝吗…

制作网站需要的技术与软件app下载汅api免费下载大全视频

针对Go语言的学习,不同阶段应采取不同的学习方式,以达到最佳效果.本文将Go的学习分为入门、实战、进阶三个阶段,下面分别详细介绍 一、社区 Go语言中文网 作为专注于Go语言学习与推广的平台,Go语言中文网为开发者提供了丰富的中…

电子商务网站建设与管理笔试用文本文档做网页

机器学习的过程中处理数据,会遇到数据可视化的问题. 大部分都是利用python的matplotlib库进行数据的可视化处理. plt.show() 默认都是输出.png文件,图片只要稍微放大一点,就糊的不行. 下面给出一段正常进行…

商品展示网站模板旅游最适合的城市

安卓有的apk 软件会不断更新。但有些用户需要旧版的有些功能或者新版功能增减原因等等。需要不更新继续使用。这类问题有的可以简单修改版本号来跳过更新。或者有的软件可以忽略。但对于某些无法跳过更新界面等等的apk。就需要深度反编译来去除软件的强制更新。 通过课程可以了…

网站公司设计wordpress站点地址无法更改

题目描述 给定一个数列,初始为空,请支持下面三种操作: 给定一个整数 x,请将 x 加入到数列中。输出数列中最小的数。删除数列中最小的数(如果有多个数最小,只删除 1 个)。 输入格式 第一行是一个…

建外贸网站哪个好网站建设公司该如何选择

Oracle 数据库中的全文搜索 0. 引言1. 整体流程2. 创建索引2-1. 创建一个简单的表2-2. 创建文本索引2-3. 查看创建的基础表 3. 运行查询3-1. 运行文本查询3-2. CONTAINS 运算符3-3. 混合查询3-4. OR 查询3-5. 通配符3-6. 短语搜索3-7. 模糊搜索(Fuzzy searches&…

手机站网站建设手机网站技巧

Spring是一款基于Java语言的轻量级开源应用框架,用于构建企业级应用程序。Spring框架拥有众多的功能模块,能够为开发者提供全面的解决方案,包括IoC容器、AOP、数据访问、Web开发、事务管理等。而MAC(Model-View-Controller、Agile…

青岛网站营销推广做设计开哪个素材网站的会员好

Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。但是官网的示例只有普通日期类型的验证,没有时间范围的验证。 一开始,我认为时间时间范围的是一…

asp网站搭建教程vue前端可视化开发工具

文章目录 写在前面Tag题目来源解题思路方法一:迭代 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾…

网站建设外包合同模板网站运营目的

在 JavaScript 开发中,我们经常需要处理对象数据,但有时这些对象可能包含一些空值或空对象。在处理数据时,通常需要将这些空值或空对象去除,以便得到更干净、更紧凑的数据结构。本文将介绍几种方法,教你如何去除 JavaS…

都江堰网站建设南京市建设执业资格中心网站

一、概述。 Hydra是一款非常强大的渗透工具,由著名的黑客组织THC开发的一款开源工具。 二、使用方法。 hybra基础语法: hydra 参数 IP 服务 参数: -l login 小写,指定用户名进行破解 -L file 大写,指定用户的用户名…

玉溪网站建设设计传奇游戏排行榜

pros and cons支持者和反对者,用于辩论from scratch 从头做起转载于:https://blog.51cto.com/techfans/160809

网站后台ftp账户东莞企业年检哪个网站做

前景 静态代码扫描是CI/CD中重要的一环,可以在代码提交到代码仓库之后,在CI/CD流程中加入代码扫描步骤,从而及时地对代码进行质量的检查。这可以有效地降低后期维护成本,优化产品质量,提高产品交付速度。同时&#xf…

中国住房和城乡建设部网站小白怎么做网站

本地文件夹上传到Github 步骤1. 下载git步骤2. 在github中新建一个库(Repository)步骤3. 设置SSH key步骤4. 添加SSH keys步骤5. 本地文件上传到github参考 步骤1. 下载git 下载git客户端,并在本地安装完成。 步骤2. 在github中新建一个库&a…

英迈思做的网站怎么样重庆工程招标网站有哪些

今天谈下业务系统性能问题分析诊断和性能优化方面的内容。这篇文章重点还是谈已经上线的业务系统后续出现性能问题后的问题诊断和优化重点。 系统性能问题分析流程 我们首先来分析下如果一个业务系统上线前没有性能问题,而在上线后出现了比较严重的性能问题&#x…