@Override
 public void put(final E e) throws InterruptedException {
   int idleCounter = 0;
   do {
     if (offer(e)) {
       return;
     }
     idleCounter = waitStrategy.idle(idleCounter);
   } while (!Thread.interrupted()); // clear interrupted flag
   throw new InterruptedException();
 }
 @Override
 public E take() throws InterruptedException {
   int idleCounter = 100;
   do {
     final E result = relaxedPoll();
     if (result != null) {
       return result;
     }
     idleCounter = waitStrategy.idle(idleCounter);
   } while (!Thread.interrupted()); // clear interrupted flag
   throw new InterruptedException();
 }
 @Override
 public boolean offer(final E e, final long timeout, final TimeUnit unit)
     throws InterruptedException {
   int idleCounter = 0;
   final long timeoutNanos = System.nanoTime() + unit.toNanos(timeout);
   do {
     if (offer(e)) {
       return true;
     } else if (System.nanoTime() - timeoutNanos > 0) {
       return false;
     }
     idleCounter = waitStrategy.idle(idleCounter);
   } while (!Thread.interrupted()); // clear interrupted flag
   throw new InterruptedException();
 }
 @Override
 public E poll(final long timeout, final TimeUnit unit) throws InterruptedException {
   int idleCounter = 0;
   final long timeoutNanos = System.nanoTime() + unit.toNanos(timeout);
   do {
     final E result = poll();
     if (result != null) {
       return result;
     } else if (System.nanoTime() - timeoutNanos > 0) {
       return null;
     }
     idleCounter = waitStrategy.idle(idleCounter);
   } while (!Thread.interrupted()); // clear interrupted flag
   throw new InterruptedException();
 }