MpscLinkedQueue 无锁队列

  • Overview
  • 数据结构
  • 实现
    • Offer
    • Poll
  • 伪共享

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 newTail;
        if (value instanceof MpscLinkedQueueNode) {
            newTail = (MpscLinkedQueueNode) value;
            newTail.setNext(null);
        } else {
            newTail = new DefaultNode(value);
        }

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

MpscLinkedQueue 无锁队列_第1张图片

Poll

private MpscLinkedQueueNode peekNode() {
        MpscLinkedQueueNode head = headRef();
        MpscLinkedQueueNode 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 next = peekNode();
        if (next == null) {
            return null;
        }

        // next becomes a new head.
        MpscLinkedQueueNode 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();
    }

MpscLinkedQueue 无锁队列_第2张图片

伪共享

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

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

你可能感兴趣的:(java,Queue)