每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

线程池中的阻塞队列?阻塞队列的四组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个正式工的工厂,面对大量生产任务时,首先考虑的应该是积压一点生产任务(放到阻塞队列中),积压不了了才再考虑增加临时工,临时工也没有指标招了那就调用拒绝策略。

posted @ 2021-06-16 19:15  雨下整夜~  阅读(75)  评论(0)    收藏  举报