洛克人java下载_JAVA 1.7并发之LinkedTransferQueue原理理解

news/2024/11/30 8:50:09/

昨天刚看完BlockingQueue觉得好高级啊,今天扫到1.7就发现了升级版。。。。

就是作者的论文啦,纯英文。。。比较难啃,但是我觉得逻辑上比看代码容易理解,其实代码什么u啊h啊看得很混

LinkedTransferQueue

起源: 我觉得是这样的,之前的BlockingQueue是对 读取 或者 写入 锁定整个队列,所以在比较繁忙的时候,各种锁比较耗时

而当时有一个SynchronizedQueue其实不能叫Queue,因为只能放一个物件,要么有一个物件在等人拿,要么有一个空等人放

根据这个原理,诞生了LinkedTransferQueue,利用CompareAndSwap进行一个无阻塞的队列,针对每一个操作进行处理样大家就不用抢得那么辛苦了

数据结构

在类的内部保持着一个栈,基本单位是node,根据 hasData区分里面有两种元素,要么是 Data 要么是 Reservation,不会同时存在

并且有一个变量head指向最前面的node,没东西则是null

Node

{

isData    是不是数据,是的话item放具体东西

item   如果不是数据则为null

next   下一个节点

waiter  如果不是数据则是reservation,有一个线程在等待

}

过程:

整个存取过程分成两部分

1:MATCH(原节点,新节点)

for (;;) { // restart on append race

for (Node h = head, p = h; p != null;) { // 如果头结点为空则跳过,非空进去找第一个可用节点

boolean isData = p.isData;

Object item = p.item;

if (item != p && (item != null) == isData) { // 判断原节点可用性,如data的item应该是数值,如果是null则表明用过了

if (isData == haveData) // 两个节点是相同类型,不用match了,去下一步

break;

if (p.casItem(item, e)) { // 节点不同类型,match成功,更改原节点item,表明不可用

for (Node q = p; q != h;) {//什么,我居然不是head节点了?我要让它指向我!

Node n = q.next; // update by 2 unless singleton

if (head == h && casHead(h, n == null ? q : n)) {

h.forgetNext();

break;

} // advance and retry

if ((h = head) == null ||

(q = h.next) == null || !q.isMatched())

break; // unless slack < 2

}

LockSupport.unpark(p.waiter);//根据原节点的类型,reservation则叫人收货,data则叫null收货

return LinkedTransferQueue.cast(item);//根据原节点的类型,reservation则返回null,data则返回数据

}

}

Node n = p.next;//下一个节点

p = (p != n) ? n : (h = head); // Use head if p offlist

}

重点是找出第一个可用节点,如果是null则跳过,如果与进来的节点相同(本来就有data,还放data)也跳过,如果不同(本来是data,现在是reservation,返回data值 / 本来是reservation,现在是data,叫人来收货,返回reservation值=空)

2:处理节点

if (how != NOW) { // No matches available

if (s == null)

s = new Node(e, haveData);

Node pred = tryAppend(s, haveData);//尝试添加新node

if (pred == null)

continue retry; // 不成功则重试整个过程

if (how != ASYNC)

return awaitMatch(s, pred, e, (how == TIMED), nanos);//根据参数,等不等别人放数据,拿数据,等多久

}

return e; // not waiting

MATCH失败了才会进入这个环节,把新节点放进栈内,并根据参数决定立刻返回或者等待返回

EXAMPLES

1:Head->Data    Input->Data

Match:      根据他们的属性 发现 cannot match ,因为是同类的

处理节点:   所以把新的data放在原来的data后面,然后head往后移一位,Reservation同理

HEAD=DATA->DATA

2:Head->Data    Input->Reservation  (取数据)

Match:      成功match,就把Data的item变为reservation的值(null,有主了),并且返回数据。

处理节点:  没动,head还在原地

HEAD=DATA(用过)

3:Head->Reservation  Input->Data(放数据)

Match:       成功match,就把Reservation的item变为Data的值(有主了),并且叫waiter来取

处理节点:  没动

HEAD=RESERVATION(用过)

总结:LinkedTransferQueue通过CAS尝试放入data或增加reservation。

其消耗小于把整个队列锁掉,但是在并发特别高的情况下大家抢着尝试一样会影响速度

至于为什么跨过了1.6到1.7这个类才出现我觉得有点神奇

简单用法介绍------------------------------------------------------------------------------------------------------

存:

put();   放元素进去队列,注意队列是可以无限长的

add();   同上

transfer();  这个是重点,如果队列中有人发现有人在等,则直接给那个人(有一个参数waiter指定了在等的线程)

如果没人在等,就放进队列

取:

poll();  立即返回,如果没有元素就是空

take(); 如果没有元素,那就等

PS:最好是用poll然后自己处理空的状况,如果全是take然后又迟迟没有东西,那就一堆内存在等了。


http://www.ppmy.cn/news/573022.html

相关文章

洛克人html5,《洛克人Zero/Zx合集》:跳票冷饭,与预期有差但依旧很香

前言 洛克人系列&#xff0c;卡普空旗下经典IP之一&#xff0c;一直都是以高难度著称&#xff0c;相信很多90后玩家的童年都有游玩洛克人的经历。从18年发布的洛克人11&#xff0c;整个系列发展有30余年&#xff0c;洛克人元组系列、X系列的合集早已上线Steam&#xff0c;Zero/…

Python多任务执行方式

一、多任务的执行方式 并发&#xff1a;在一段时间内交替去执行任务&#xff08;单核CPU&#xff09;并行&#xff1a;CPU核数大于任务数 二、进程&#xff08;实现多任务&#xff09;——操作系统调度 进程是操作系统进行资源分配的基本单元一个程序至少有一个进程&#xf…

网关全局过滤器:Java中的强大工具

文章目录 网关过滤器简介网关过滤器的作用过滤器的生命周期实际应用示例权限过滤器解析 总结 网关过滤器简介 网关过滤器是一个位于应用程序和底层服务之间的组件&#xff0c;它截取进出网络请求&#xff0c;并提供对请求和响应进行处理的机制。它可以在请求到达目标服务之前或…

10种常用排序算法

10种常用排序算法 0——序言 以下是常用的排序算法及其对应的时间复杂度&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a; 最好情况时间复杂度&#xff1a;O(n)平均情况时间复杂度&#xff1a;O(n^2)最坏情况时间复杂度&#xff1a;O(n^2) 选择排序&a…

c++11中的多线程std::thread

c11中的多线程std::thread 在c11中提供了新的多线程的创建方式std::thread, 丰富了对于多线程的使用。 std::thread类的构造函数的格式如下所示&#xff1a; thread() noexcept; //default constructor 其中noexcept表示函数不会抛出异常&#xff0c;如果抛出异常程序…

深入探究 ReentrantLock 的应用和原理

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

Ajax技术的秘密揭秘:异步传输,高效交互

文章目录 I. 什么是AjaxAjax的定义和起源Ajax与传统的Web应用程序之间的区别 II. Ajax的工作原理Ajax的基本原理Ajax如何通过异步传输实现无需刷新页面 III. Ajax的应用场景在Web应用程序中应用Ajax的优势Ajax在哪些场景中使用 IV. Ajax的组成部分和APIXHR对象FormData对象Fetc…

C# 中使用枚举转换时需要注意的坑点及解决方案

在使用枚举进行转换时&#xff0c;需要注意一些细节&#xff0c;否则可能会出现一些意外情况。本文将介绍一些在枚举转换中需要注意的坑点&#xff0c;并提供一些解决方案。 1、枚举从 int 值转换的坑 在将 int 值转换成枚举类型时&#xff0c;可能会遇到一些问题。即使 int …