hashmap及ConcurrentLinkedQueue等集合

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值