protected E getSingleConsumerNodeValue(LinkedQueueAtomicNode<E> currConsumerNode, LinkedQueueAtomicNode<E> nextNode) {
        // we have to null out the value because we are going to hang on to the node
        final E nextValue = nextNode.getAndNullValue();
        // Fix up the next ref of currConsumerNode to prevent promoted nodes from keeping new ones alive.
        // We use a reference to self instead of null because null is already a meaningful value (the next of
        // producer node is null).
        currConsumerNode.soNext(currConsumerNode);
        spConsumerNode(nextNode);
        // currConsumerNode is now no longer referenced and can be collected
        return nextValue;
    }
{@inheritDoc} <br>
<p>
IMPLEMENTATION NOTES:<br>
Queue is empty when producerNode is the same as consumerNode. An alternative implementation would be to
observe the producerNode.value is null, which also means an empty queue because only the
consumerNode.value is allowed to be null.

@see MessagePassingQueue#isEmpty()
jctools-core/src/main/java/org/jctools/queues/atomic/unpadded/BaseLinkedAtomicUnpaddedQueue.java