privatestaticfinal ArrayBlockingQueue<String> QUEUE = new ArrayBlockingQueue<>(10);
privatestaticfinal CountDownLatch LATCH = new CountDownLatch(2);
publicstaticvoidmain(String[] args){
ExecutorService pool = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), new ThreadFactoryBuilder().setNameFormat("Thread-pool-%d").build(), new ThreadPoolExecutor.AbortPolicy());
pool.submit(() -> { for (int i = 0; i < 100; i++) { try { Thread.sleep(1000L);
public E poll(){ final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : dequeue(); } finally { lock.unlock(); } }
public E take()throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await(); return dequeue(); } finally { lock.unlock(); } }
通过源码可以看出:
pool 和 take 都是从队列中获取元素,二者不同的是,当队列中没有元素时,poll 方法返回 null,而 take 方法会一直阻塞等待,直到从队列中获取到元素。
poll 和 take 方法获取元素都是调用的 dequeue 方法。
private E dequeue(){ // assert lock.getHoldCount() == 1; // assert items[takeIndex] != null; final Object[] items = this.items; @SuppressWarnings("unchecked") // 获取元素并将元素置为 null E x = (E) items[takeIndex]; items[takeIndex] = null; // takeIndex 下一个 take, poll, peek or remove 的索引 // 指向下一个元素,并且 元素数减少 if (++takeIndex == items.length) takeIndex = 0; count--; // 更新迭代器状态 if (itrs != null) itrs.elementDequeued(); // 唤醒等待放入元素的线程 notFull.signal(); return x; }
查看元素
public E peek(){ final ReentrantLock lock = this.lock; lock.lock(); try { return itemAt(takeIndex); // null when queue is empty } finally { lock.unlock(); } }