private ByteBuffer getBuffer(final int minCapacity) {
        final int offset = getOffset(minCapacity);
        final Queue<ByteBuffer> byteBufferQueue = getByteBufferQueue(offset);
        final Semaphore semaphore = getSemaphore(offset);

        boolean havePermit = semaphore.tryAcquire();
        ByteBuffer buffer;

        if (havePermit) {
            // Queue could be empty at this point, i.e. fresh pool or all are in use.
            buffer = byteBufferQueue.poll();
            if (buffer == null) {
                // This should not really  happen but if there was nothing in the queue then we
                // need to give back our permit.
                semaphore.release();
            }
        } else {
            // No buffers in the pool to use so we need to create one if the pool is not full
            buffer = createNewBufferIfAllowed(offset);
        }

        if (buffer == null) {
            try {
                // Must be at max pooled buffers so we have to wait for another thread to release a permit
                semaphore.acquire();
                // Now we have a permit we can safely get a buffer from the queue
                buffer = byteBufferQueue.poll();
            } catch (InterruptedException e) {
                LOGGER.error("Thread interrupted", e);
                Thread.currentThread().interrupt();
            }
        }

        Objects.requireNonNull(buffer);
        // Ensure the buffer is ready for use with limits/positions/marks cleared
        buffer.clear();
        return buffer;
    }
An bounded self-populating pool of directly allocated ByteBuffers.
The pool holds buffers in a fixed set of sizes and any request for a buffer
will result in a buffer with capacity >= the requested capacity being
returned.
All buffers are cleared ready for use when obtained from the pool.
Once a buffer has been returned to the pool it MUST not be used else
bad things will happen.
<p>
This impl uses lock free {@link ConcurrentLinkedQueue} and {@link Semaphore}
stroom-bytebuffer/src/main/java/stroom/bytebuffer/ByteBufferPoolImpl5.java