Jctools Queue队列

JCTools是一款对jdk并发数据结构进行增强的并发工具,主要提供了非阻塞Map以及无锁Queue的增强数据结构,关于NonBlockingHashMap
源码分析我写了篇文章。
如果还不了解CAS,可以参考这个博客http://blog.csdn.net/hsuxu/article/details/9467651
主要说下JCTools中的Queue,和jdk中的Queue比性能有很大的提升,主要实现利用了CAS和填充缓存行(避免伪共享),典型的空间换时间,然后我在百度时很多文章千篇一律不知道是不是抄袭,最蛋疼的是很多文章都提到“使用lazySet替代volatile set”这个主要是指Unsafe中的putOrderedObject,jdk并发包下常用 Unsafe的几个方法putOrderedObject,putObjectVolatile,compareAndSwapObject等,回到lazySet问题,很多文章都会提到一句话“这种性能提升是有代价的,虽然廉价,也就是写后结果并不会被其他线程看到,甚至是自己的线程,通常是几纳秒后被其他线程看到,lazySet的写在实践上来延迟是纳秒级,这个时间比较短,所以代价可以忍受。”,如果这玩意有延迟将是致命的或者有其他方法解决,所以我去看了下代码,mmp,这些文章乱写一通,尼玛,下面挑选一个类MpmcArrayQueue分析下源码具体看下是如何利用CAS的:

public E poll() {
        long[] sBuffer = this.sequenceBuffer;
        long mask = this.mask;
        long pIndex = -1L;

        long cIndex;
        long seq;
        long seqOffset;
        long expectedSeq;
        do {
            cIndex = this.lvConsumerIndex();
            seqOffset = calcSequenceOffset(cIndex, mask);
            seq = this.lvSequence(sBuffer, seqOffset);
            expectedSeq = cIndex + 1L;
            if (seq < expectedSeq) {
                if (cIndex >= pIndex && cIndex == (pIndex = this.lvProducerIndex())) {
                    return null;
                }

                seq = expectedSeq + 1L;
            }
        } while(seq > expectedSeq || !this.casConsumerIndex(cIndex, cIndex + 1L));

        long offset = calcElementOffset(cIndex, mask);
        E e = UnsafeRefArrayAccess.lpElement(this.buffer, offset);
        UnsafeRefArrayAccess.soElement(this.buffer, offset, (Object)null);
        this.soSequence(sBuffer, seqOffset, cIndex + mask + 1L);
        return e;
    }

上面方法是poll方法,看下11行的lvConsumerIndex方法是获取消费者索引的,这个字段是volatile修饰的,关于volatile就不用多讲了吧,22行casConsumerIndex方法底层调用了compareAndSwapLong方法,26行soElement底层调用了putOrderedObject,看到了吗,是调用putOrderedObject将数据存储,使用读取volatile字段保证数据可见性。非“使用lazySet替代volatile set”。
offer方法是类似的,就不贴代码了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值