Java高频面试题:什么是阻塞队列?

1.什么是阻塞线程?

阻塞队列和普通的队列的区别是:

当阻塞队列是空的,从队列中获取元素的操作将会被阻塞;

当阻塞队列是满的,往队列里添加元素的操作将会被阻塞;

试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素;

同样,试图从满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他线程从列中移除一个或者多个元素或者完全清空队列使队列重新变得空闲起来并后续新增。

在多线程领域里:所谓阻塞,在某些情况下会挂起线程,一旦条件满足,被挂起的线程又会自动被唤醒。

2.为什么需要BlockingQueue?

好处是我们不需要关心什么时候需要阻塞线程,什么时候需要唤起线程,因为这一切BlockingQueue都给你一手包办了。

在concurrent包发布以前,在多线程环境下,我们每个程序员必须去自己控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。

3.有哪些常见的阻塞队列?(加粗的是常用的)

  • ArrayBlockingQueue:由数组结构组成的有界阻塞队列
  • LinkedBlockingQueue:由链表结构组成的有界(但大小默认值为Integer.MAX_VALUE)阻塞队列
  • PriorityBlockingQueue:支持优先级排序的无界阻塞队列
  • DelayBlockingQueue:使用优先级队列实现的延迟无界阻塞队列
  • SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列,只存一个元素
  • LinkedTransferQueue:由链表结构组成的无界阻塞队列
  • LinkedBlockingDeque:由链表结构组成的双向阻塞队列

SynchronousQueue没有容量。与其他BlockingQueue不同,SynchronousQueue是不存储元素,每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然。

4.BlockingQueue的核心方法

BlockingQueue的核心方法:

插入 add(e) offer(e) put(e) offer(e,time,unit)

移除 remove() poll() take() poll(time,unit)

检查 element() peek()

  • 当阻塞队列满的时候,再往队列里add插入元素会抛出IllegalStateException: Queue full异常;
  • 当阻塞队列空的时候,再往队列里remove移除元素,会抛出NoSuchElementException异常;
  • 使用offer(e)添加元素,不抛异常,成功返回true,失败返回false;
  • 使用poll()移除元素时,不抛异常,成功返回队列里的元素值,失败返回null;
  • 当阻塞队列满的时候,生产者线程继续使用put(e)插入元素,会一直阻塞直到put成功,或者响应中断退出;
  • 当阻塞队列空的时候,消费者线程试图从队列里take元素,队列会一直阻塞,直到消费者线程可用;
  • 当阻塞队列满时,会等待一段时间,超时后退出:offer(e,time,unit)和poll(time,unit)。

演示示例:

(1)ArrayBlockingQueue添加元素示例:创建了一个大小为3的阻塞队列,当存入第四个元素的时候,抛出IllegalStateException: Queue full异常。
public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        System.out.println(blockingQueue.add('a'));
        System.out.println(blockingQueue.add('b'));
        System.out.println(blockingQueue.add('c'));
        System.out.println(blockingQueue.add('d'));
    }
}
报错:Exception in thread "main" java.lang.IllegalStateException: Queue full
(2)ArrayBlockingQueue移除元素示例:当阻塞队列为空时,移出元素抛出NoSuchElementException异常
public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue blockingQueue = new ArrayBlockingQueue(3);
        System.out.println(blockingQueue.add('a'));
        System.out.println(blockingQueue.add('b'));
        System.out.println(blockingQueue.add('c'));
//        System.out.println(blockingQueue.add('d'));
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
    }
}

报错:NoSuchElementException

全部评论
可以
点赞 回复 分享
发布于 2021-03-20 16:14
感谢参与【创作者计划2期·技术干货场】!欢迎更多牛油来写干货,瓜分总计20000元奖励!!技术干货场活动链接:https://www.nowcoder.com/link/czz2jsghtlq(参与奖马克杯将于每周五结算,敬请期待~)
点赞 回复 分享
发布于 2021-03-15 20:35

相关推荐

有担当的灰太狼又在摸鱼:零帧起手查看图片
点赞 评论 收藏
分享
05-12 18:24
长安大学 UE4
因为是家里第一代大学生,报专业报学校都没人可以指导,只能自己看着来毕业找工作,父母只知道考公务员啊考教师啊,丝毫不考虑难度我说要去大城市打工才行,小县城对学历没有需求,开的工资都很低,两三千养活不了的结果都不同意我去大城市,觉得北上广深远,不稳定,一年到头不着家,养这么大孩子算白养了要我怎么办,不考公不考编就是死路一条呗,出去打工就是不孝呗可是考公考编也好难,考上也是小职员,到时候又变成了家里第一代体制内了,不还是样样靠自己有时候很羡慕同学,要去大城市打拼,家里都很支持去看看外面的世界也羡慕同学父母都是体制内的,考上还有所依靠家里没有办法给予帮助,简直是进入死胡同一样
Two_Shadow:你先拿到offer,路是自己走的,你真去了谁拦得住你呢,不用给自己扣帽子,我也是我家第一代大学生啊,农村人,高考96个志愿我就填50多个计算机,爸妈让我填满保底我说我不,我就学计算机,上大学了让我考研我说我不考,我就喜欢干活,现在签了offer,他们也释怀,不回家就努力提升自己,就往家里打钱,就开视频,还能怎么样呢,路是自己走的,他们只是希望你能走得好一点,但大部分父母,尤其是农村父母根本帮不了你什么,难道你就不走路了吗,希望能骂醒你,不要想太多做太少。
点赞 评论 收藏
分享
评论
5
13
分享

创作者周榜

更多
牛客网
牛客企业服务