hashmap及ConcurrentLinkedQueue等集合

来源:互联网 发布:2017年淘宝活动时间表 编辑:程序博客网 时间:2024/06/06 01:42

hashmap:当length=2^n时,hashcode & (length-1) == hashcode % length

http://www.iteye.com/topic/754887

http://www.iteye.com/topic/539465

http://www.blogjava.net/xylz/archive/2010/07/20/326584.html



解析ConcurrentLinkedQueue

http://www.blogjava.net/xylz/archive/2010/07/23/326934.html

清单1 入队列操作

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    Node<E> n = new Node<E>(e, null);
    for (;;) {
        Node<E> t = tail;
        Node<E> s = t.getNext();
        if (t == tail) {
            if (s == null) {
                if (t.casNext(s, n)) {//将n修改成为尾节点t的下一个节点
                    casTail(t, n);//将尾节点指针tail后移,指向n,使n成为尾节点

                    return true;
                }
            } else {
                casTail(t, s);//将尾节点指针tail指向s,使s成为尾节点
            }
        }
    }
}

清单1 描述的是入队列的过程。整个过程是这样的。

    1. 获取尾节点t,以及尾节点的下一个节点s。如果尾节点没有被别人修改,也就是t==tail,进行2,否则进行1。
    2. 如果s不为空,也就是说此时尾节点后面还有元素,那么就需要把尾节点往后移,进行1。否则进行3。
    3. 修改尾节点的下一个节点为新节点,如果成功就修改尾节点,返回true。否则进行1。

从操作3中可以看到是先修改尾节点的下一个节点,然后才修改尾节点位置的,所以这才有操作2中为什么获取到的尾节点的下一个节点不为空的原因。

特别需要说明的是,对尾节点的tail的操作需要换成临时变量t和s,一方面是为了去掉volatile变量的可变性,另一方面是为了减少volatile的性能影响。


0 0