JAVA 1.7并发之LinkedTransferQueue原理理解

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

如果对内容觉得不够充分,可以去看http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf

就是作者的论文啦,纯英文。。。比较难啃,但是我觉得逻辑上比看代码容易理解,其实代码什么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.<E>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然后又迟迟没有东西,那就一堆内存在等了。

JAVA 1.7并发之LinkedTransferQueue原理理解,布布扣,bubuko.com

时间: 2024-10-16 17:12:43

JAVA 1.7并发之LinkedTransferQueue原理理解的相关文章

Java内存的原型及工作原理理解

一.java虚拟机内存原型 寄存器:我们在程序中无法控制. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 堆:存放用new产生的数据 静态域:存放在对象中用static定义的静态成员 常量池:存放常量 非RAM存储:硬盘等永久存储空间. 二.常量池(constant pool) 常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据.除了包含代码中所定义的各种基本类型(如int.long等等)和对象型(如String及数组)的常量值(final)

【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译==>Java字节码 ==通过类加载器==>JVM(jvm执行字节码)==转化为汇编指令==>CPU上执行. Java中使用的并发机制依赖于JVM的实现和CPU的指令. volatile初探 volatile是是轻量级的synchronized,它在多处理器开发中保证了共享变量的可见性.可见性

ConcurrentHashMap源码解读及原理理解

ConcurrentHashMap结构图如下: ConcurrentHashMap实现类图如下: segment的结构图如下: package concurrentMy.juc_collections.hashMap; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.util.AbstractCollection; import java.

Java集合详解5:深入理解LinkedHashMap和LRU缓存

Java集合详解5:深入理解LinkedHashMap和LRU缓存 今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech 文章首发于我的个人博客: https://h2pl.github.io/2018/05/11/collection5 更多关于Java后端学习的内容请到我的CSDN博客上查看:https://blog.csdn.net

Java 并发工具CountDownLatch和CyclicBarrier 原理解析

[TOC] Java 并发工具CountDownLatch和CyclicBarrier 原理解析 一,简介 CountDownLatch 允许一个或者多个线程等待其他线程完成操作. CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程达到一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行. 二,代码演示 CountDownLatchDemo public class Co

Java垃圾回收机制的工作原理

Java垃圾回收机制的工作原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 一.Java中引入垃圾回收机制的作用 当我们建完类之后,创建对象的同时,进行内存空间的分配,为了防止内存空间爆满,java引入了垃圾回收机制,将不再引用的对象进行回收,释放内存,循环渐进,从而防止内存空间不被爆满. 1.垃圾回收机制的工作原理 创建的对象存储在堆里面,把堆比喻为院子中的土地,把对象比喻为土地的管理者,院子比喻为java虚拟机,当创建一个对象时,java虚拟机将给

POJ1523(求连用分量数目,tarjan算法原理理解)

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7406   Accepted: 3363 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

JAVA 1.5 并发之 Executor框架 (二)execute VS submit

http://www.cnblogs.com/rockman12352/p/3788688.html 上一篇对于整体框架讲了很多东西,但是具体在使用时有一些细节并没有说出来 首先是执行任务 execute(); 执行任务,返回空,相当于 new Thread(task).start(); submit();   执行任务,但是会返回一个future<T>,就是计算好的结果,如果没有计算好则会阻塞,还有一个好处是可以管理exception public static void main(Stri

Java远程通讯可选技术及原理

Java远程通讯可选技术及原理——转 在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术, 例如:RMI.MINA.ESB.Burlap.Hessian.SOAP.EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢, 了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了, 在这篇blog中我们将来一探究竟,抛砖引玉,欢迎大家提供更多的实现远程通讯的技术