ConcurrentLinkedQueue

来源:互联网 发布:软件开发需求文档模板 编辑:程序博客网 时间:2024/06/05 03:24

队列、链表之类的数据结构及其常用。Java中,ArrayList和Vector都是使用数组作为其内部实现。两者最大的不同在于:Vector是线程安全的,而ArrayList不是。此外LinkedList使用链表的数据结构实现了List,但并不是线程安全的,就像之前包装HashMap,这里我们可以使用Collections.synchronizedList()来包装任意List。此时,生成的List对象就是线程安全的。

public static List<String> l = Collections.synchronizedList(new LinkedList<String>());

高效读写的队列:深度剖析ConcurrentLinkedQueue

 JDK中,提供了一个ConcurrentLinkedQueue类来实现高并发的队列。这个队列使用链表作为其数据结构。这个类算是高并发环境中性能最好的队列。高性能是因为其内部复杂的实现。

链表内的节点:

    private static class Node<E> {        volatile E item;        volatile Node<E> next;    ...

其实这是一个静态内部类,item是来表示元素的。next表示当前Node的下一个元素。 
对Node进行操作时,使用了CAS操作:

//表示设置当前Node的item值。第一个参数为期望值,第二个参数为设置目标值。当当前值等于期望值时(就是没有被其他人改过),就会将目标设置为val。boolean casItem(E cmp, E val) {    return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);}//和上个方法类似,是用来设置next字段。boolean casNext(Node<E> cmp, Node<E> val) {    return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);}

ConcurrentLinkedQueue内部有两个重要的字段:head和tail,分别表示链表的头部和尾部,当然都得是Node类型。对于head来说,它永远不会为null,并且通过head和succ()后继方法一定能完整地遍历整个链表。对于tail来说,它自然表示队列的末尾。 
以下是构造函数:

    public ConcurrentLinkedQueue() {        head = tail = new Node<E>(null);    }

但是ConcurrentLinkedQueue的内部实现非常复杂,它允许在运行时链表处于多个不同的状态。以tail为例,一般来说我们期望tail总是作为链表的末尾,但实际上tail的更新并不是及时的,可能会产生拖延现象。就是说,有可能指向的并不是真正的尾巴,真正的可能在后面一个或者多个。

有三个函数需要注意的:

peek()获取元素 不移除头结点

poll() 获取元素并且在队列中移除,如果队列为空返回null

offer()将指定元素插入到此队列的尾部。

toArray

返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。如果指定的数组能容纳队列,则将该队列返回此处。否则,将分配一个具有指定数组的运行时类型和此队列大小的新数组。
如果指定的数组能容纳队列,并有剩余的空间(即数组的元素比队列多),那么会将紧接队列尾部的元素设置为 null。
像 toArray() 方法一样,此方法充当基于数组的 API 与基于 collection 的 API 之间的桥梁。更进一步说,此方法允许对输出数组的运行时类型进行精确控制,在某些情况下,这可以用来节省分配开销。
    假定 x 是只包含字符串的一个已知队列。以下代码用来将该队列转储到一个新分配的 String 数组.


注意:

1.ConcurrentLinkedQueue的API原来.size()是要遍历一遍集合的,所以尽量要避免用size而改用isEmpty().

2.如果直接使用它提供的函数,比如:queue.add(obj); 或者 queue.poll(obj);,这样我们自己不需要做任何同步。
但如果是非原子操作,比如:

[java] view plain copy
 print?
  1. if(!queue.isEmpty()) {    
  2.    queue.poll(obj);    
  3. }    

原创粉丝点击