ClosableBlockingQueue { public E getElementBlocking() throws InterruptedException { lock.lock(); try { while (open && elements.isEmpty()) { nonEmpty.await(); } if (open) { return elements.removeFirst(); } else { throw new IllegalStateException("queue is closed"); } } finally { lock.unlock(); } } ClosableBlockingQueue();  ClosableBlockingQueue(int initialSize);  ClosableBlockingQueue(Collection<? extends E> initialElements); int size(); boolean isEmpty(); boolean isOpen(); boolean close(); boolean addIfOpen(E element); void add(E element); E peek(); E poll(); List<E> pollBatch(); E getElementBlocking(); E getElementBlocking(long timeoutMillis); List<E> getBatchBlocking(); List<E> getBatchBlocking(long timeoutMillis); @Override int hashCode(); @Override boolean equals(Object obj); @Override String toString();  }
@Test public void testGetElementBlocking() { try { ClosableBlockingQueue<String> queue = new ClosableBlockingQueue<>(); assertNull(queue.getElementBlocking(1)); assertNull(queue.getElementBlocking(3)); assertNull(queue.getElementBlocking(2)); assertEquals(0, queue.size()); queue.add("a"); queue.add("b"); queue.add("c"); queue.add("d"); queue.add("e"); queue.add("f"); assertEquals(6, queue.size()); assertEquals("a", queue.getElementBlocking(99)); assertEquals("b", queue.getElementBlocking()); assertEquals(4, queue.size()); assertEquals("c", queue.getElementBlocking(0)); assertEquals("d", queue.getElementBlocking(1000000)); assertEquals("e", queue.getElementBlocking()); assertEquals("f", queue.getElementBlocking(1786598)); assertEquals(0, queue.size()); assertNull(queue.getElementBlocking(1)); assertNull(queue.getElementBlocking(3)); assertNull(queue.getElementBlocking(2)); assertTrue(queue.close()); try { queue.getElementBlocking(); fail("should cause an exception"); } catch (IllegalStateException ignored) { } try { queue.getElementBlocking(1000000000L); fail("should cause an exception"); } catch (IllegalStateException ignored) { } } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }