MpscLinkedQueue 无锁队列

Overview

  1. Netty的无锁队列
  2. 适用于单消费者多生产者场景
  3. A lock-free concurrent single-consumer multi-producer Queue

数据结构

里面有三种需要提一下的数据结构

Node, DefaultNode, Ref
1. Node: 声明了的next, volatile型, 还有AtomicReferenceFieldUpdater对next进行修改
2. DefaultNode: Node的实现类, 声明了value
3. Ref: 分为TailRef和HeadRef, 分别声明了volatile的tailRef和headRef引用…还有各自的AtomicReferenceFieldUpdater

实现

Offer

public boolean offer(E value) {
        if (value == null) {
            throw new NullPointerException("value");
        }

        final MpscLinkedQueueNode<E> newTail;
        if (value instanceof MpscLinkedQueueNode) {
            newTail = (MpscLinkedQueueNode<E>) value;
            newTail.setNext(null);
        } else {
            newTail = new DefaultNode<E>(value);
        }

        MpscLinkedQueueNode<E> oldTail = getAndSetTailRef(newTail);
        oldTail.setNext(newTail);
        return true;
    }

Offer

Poll

private MpscLinkedQueueNode<E> peekNode() {
        MpscLinkedQueueNode<E> head = headRef();
        MpscLinkedQueueNode<E> next = head.next();
        if (next == null && head != tailRef()) {
            // if tail != head this is not going to change until consumer makes progress
            // we can avoid reading the head and just spin on next until it shows up
            //
            // See https://github.com/akka/akka/pull/15596
            do {
                next = head.next();
            } while (next == null);
        }
        return next;
    }

public E poll() {
        final MpscLinkedQueueNode<E> next = peekNode();
        if (next == null) {
            return null;
        }

        // next becomes a new head.
        MpscLinkedQueueNode<E> oldHead = headRef();
        // Similar to 'headRef.node = next', but slightly faster (storestore vs loadstore)
        // See: http://robsjava.blogspot.com/2013/06/a-faster-volatile.html
        // See: http://psy-lob-saw.blogspot.com/2012/12/atomiclazyset-is-performance-win-for.html
        lazySetHeadRef(next);

        // Break the linkage between the old head and the new head.
        oldHead.unlink();
        return next.clearMaybe();
    }

poll and peek

伪共享

long p00, p01, p02, p03, p04, p05, p06, p07;
long p30, p31, p32, p33, p34, p35, p36, p37;

队列中有定义这样一组变量, 据说是关于伪共享, 尚未研习…
有Link: 从Java视角理解系统结构(三)伪共享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>