FairQueue implements BlockingQueue<E> { @Override public E take () throws InterruptedException { E x; int c = -1; final AtomicInteger count = this.count; final ReentrantLock lock = this.lock; lock.lockInterruptibly (); try { while (count.get () == 0) { notEmpty.await (); } x = getNext (true); c = count.getAndDecrement (); if (c > 1) { notEmpty.signal (); } } finally { lock.unlock (); } return x; } FairQueue(); @Override int size(); @Override int remainingCapacity(); @Override void put(E e); @Override boolean offer(E e); @Override boolean offer(E e, long timeout, TimeUnit unit); @Override E take(); @Override E peek(); @Override E poll(); @Override E poll(long timeout, TimeUnit unit); @Override int drainTo(Collection<? super E> c); @Override int drainTo(Collection<? super E> c, int maxElements); @Override void clear(); @Override boolean contains(Object o); @Override Object[] toArray(); @Override T[] toArray(T[] a); @Override Iterator<E> iterator(); @Override E remove(); @Override E element(); @Override boolean isEmpty(); @Override boolean containsAll(Collection<?> c); @Override boolean addAll(Collection<? extends E> c); @Override boolean removeAll(Collection<?> c); @Override boolean retainAll(Collection<?> c); @Override boolean add(E e); @Override boolean remove(Object o);  }
@Test public void testTake() throws InterruptedException { new Thread(() -> { try { Thread.sleep(2000); } catch (InterruptedException suppressed) {} queue.offer(new FairQueueTestString("key1", "item1")); }).start(); FairQueueTestString s = queue.take(); Assert.assertNotNull(s); Assert.assertEquals(s.getItem(), "item1"); Assert.assertEquals(queue.size(), 0); }