线程池中的阻塞队列?阻塞队列的四组API
线程池中的阻塞队列?阻塞队列的四组API
四组API:
方式 | 抛出异常 | 返回值 | 阻塞 等待 | 超时等待 |
---|---|---|---|---|
添加 | add | offer | put | offer(E e, long timeout, TimeUnit unit) |
移除 | remove | poll | take | poll(long timeout, TimeUnit unit) |
检测队首元素 | element | peek |
为什么使用阻塞队列?
-
普通队列只能维持一个有限的缓冲区,超出缓冲区的任务无法加入,具体来说普通队列中的方法是offer和poll方法,操作失败返回false。而阻塞队列使用的是take和put的方法会阻塞操作,保持想要入队的任务。
-
在队列没有任务时会使用take阻塞获取人物的线程进入wait状态,释放cpu资源
//此处是ArrayBlockingQueue中put的源码 public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) notFull.await(); enqueue(e); } finally { lock.unlock(); } }
-
阻塞队列自带等待、唤醒功能,不需要其他额外的处理,而且不会一直占用cpu(类比生产者、消费者模式?)
为什么先加入到阻塞队列而不先尝试开辟线程?
开辟新的的线程消耗过大,需要分配内存资源,分配mainlock锁,因此首先需要考虑的是缓存先要处理的任务,在缓存不了时,再增加新的线程处理。
举个例子:
对于一个有10个正式工的工厂,面对大量生产任务时,首先考虑的应该是积压一点生产任务(放到阻塞队列中),积压不了了才再考虑增加临时工,临时工也没有指标招了那就调用拒绝策略。