@Override
        public E poll() {
            // local load of fields to avoid repeated loads after volatile reads
            final long[] sBuffer = sequenceBuffer;
            final long mask = this.mask;
            final Producer<E> producer = this.producer;
            long currentConsumerIndex;
            long sOffset;
            long pIndex = -1; // start with bogus value, hope we don't need it
            while (true) {
                currentConsumerIndex = lvConsumerIndex();// LoadLoad
                sOffset = calcSequenceOffset(currentConsumerIndex, mask);
                final long delta = lvSequence(sBuffer, sOffset) - (currentConsumerIndex + 1);

                if (delta == 0) {
                    if (casConsumerIndex(currentConsumerIndex, currentConsumerIndex + 1)) {
                        // Successful CAS: full barrier
                        break;
                    }
                    // failed cas, retry 1
                } else if (delta < 0 && // slot has not been moved by producer
                        currentConsumerIndex >= pIndex && // test against cached pIndex
                        currentConsumerIndex == (pIndex = producer.lvProducerIndex())) { // update pIndex if
                                                                                         // we must
                    // strict empty check, this ensures [Queue.poll() == null iff isEmpty()]
                    return null;
                }

                // another consumer beat us and moved sequence ahead, retry 2
            }

            return consumeElement(sBuffer, buffer, mask, currentConsumerIndex, sOffset);
        }
{@inheritDoc}
<p>
Because return null indicates queue is empty we cannot simply rely on next element visibility for poll and
must test producer index when next element is not visible.
jctools-experimental/src/main/java/org/jctools/queues/alt/MpmcArrayConcurrentQueue.java