code: public int take() {
  
          // non volatile read  ( which is quicker )
          final int readLocation = this.consumerReadLocation;
  
          // sets the nextReadLocation my moving it on by 1, this may cause it it wrap back to the start.
          final int nextReadLocation = blockForReadSpace(readLocation);
  
          // purposely not volatile as the read memory barrier occurred above when we read 'writeLocation'
          final int value = data[readLocation];
  
          setReadLocation(nextReadLocation);
  
          return value;
  
      }
docs: Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.
  <p> the reads must always occur on the same thread
  
  @return the head of this queue