曾经被面试过BlockingQueue吗?

面试时曾经被问过阻塞队列吗?

想必很多人面试时有被问到阻塞队列的经历。我们经常会在各种代码中见到或者用到它,最经常见到的地方就是线程池。

但是如果问起阻塞队列的原理,它是基于什么实现的,你是否说的上来呢?

陌生又熟悉的BlockingQueue

阻塞队列(BlockingQueue)其实也是队列,但是它有两个特点, · 当队列满时,往队列的put()操作会导致当前线程阻塞 · 当队列空时,向队列的take()操作也会导致当前线程阻塞

BlockingQueue经常用在以下几个场景 · 生产者&消费者 · 线程间通信 · 线程池

问题1:add()和put()有什么不同?

相信很多人都知道,add()其实并不是阻塞操作,当队列满时add()会抛出异常,而put()不会抛出异常。

问题2:阻塞队列的原理是什么?

看过上一篇文章的朋友肯定立马想到BlockingQueue是基于Condition,我们可以用很简单的代码写出阻塞队列的原理

final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();

final Object[] items = new Object[100];
int putptr, takeptr, count;

public void put(Object x) throws InterruptedException {
    lock.lock();
    try {
        while (count == items.length) {
            notFull.await();
        }

        items[putptr] = x;
        if (++putptr == items.length)
            putptr = 0;
        ++count;
        notEmpty.signal();
    } finally {
        lock.unlock();
    }
}

public Object take() throws InterruptedException {
    lock.lock();
    try {
        while (count == 0) {
            notEmpty.await();
        }
        Object x = items[takeptr];
        if (++takeptr == items.length)
            takeptr = 0;
        --count;
        notFull.signal();
        return x;
    } finally {
        lock.unlock();
    }
}

以put()为例说明,当队列满时,当前线程会等待notFull条件满足,若不满足则持续等待。直到有take()操作,队列的notFull条件满足,才会往队列放对象,同时让notEmpty条件满足,对应的take()操作才能正常进行。

总结

看完这篇文章,相信你已经明白阻塞队列的实现原理了吧。以下是它的主要子类 · ArrayBlockingQueue · LinkedBlockingQueue · SynchronousQueue 虽然它们的具体实现各不相同,但是原理都是一样基于Condition去实现的。

下次面试时被问到BlockingQueue的话就可以淡定的说啦! 欢迎订阅关注!

原文发布于微信公众号 - Android每日一讲(gh_f053f29083b9)

原文发表时间:2018-02-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ryan Miao

java并发编程实战学习(3)--基础构建模块

转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和p...

32070
来自专栏微信终端开发团队的专栏

iOS微信安装包瘦身

前提 微信经过多次版本迭代,产生不少冗余代码和无用资源。之前微信也没有很好的手段知道哪个模块增量多少。另外去年10月微信开始做ARC支持,目的是为了减少野指针带...

948100
来自专栏老马说编程

(81) 并发同步协作工具 / 计算机程序的思维逻辑

查看历史文章,请点击上方链接关注公众号。 我们在67节和68节实现了线程的一些基本协作机制,那是利用基本的wait/notify实现的,我们提到,Java并发包...

20690
来自专栏我叫刘半仙

【JDK并发包基础】线程池详解

        为了更好的控制多线程,JDK提供了一套线程框架Executor来帮助程序员有效的进行线程控制。Java.util.concurrent 包是专为...

66250
来自专栏公众号_薛勤的博客

Java中的并发工具类(CountDownLatch,CyclicBarrier,Semaphore,Exchanger)

在JDK的并发包里提供了很多有意思的并发工具类。CountDownLatch、CyclicBarrier和Semaphore 工具类提供了一种并发流程控制的手段...

12650
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 命令执行(二)之执行隔离策略

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixThreadPoolProperties 3. HystrixThreadPoo...

50060
来自专栏大内老A

[WCF权限控制]从两个重要的概念谈起:Identity与Principal[下篇]

毫不夸张地说,安全主体(Principal)是整个授权机制的核心。我们可以简单地将将安全主体定义成能够被成功实施授权的主体。一个安全主体具有两个基本的要素:基于...

23780
来自专栏屈定‘s Blog

设计模式--责任链模式的思考

责任链模式: 客户端发出的请求,客户端本身并不知道被哪一个对象处理,而直接扔给对象链,该请求在对象链中共享,由对象本身决定是否处理. 当请求被处理后该链终止.本...

50030
来自专栏FreeBuf

VMware更新 | 修复Apache Flex BlazeDS中的漏洞

VMware发布了数个产品的版本更新,目的是修复Apache Flex BlazeDS中的一个漏洞。 据VMware介绍,Flex BlazeDS组件应用在数个...

22750
来自专栏码神联盟

Shiro系列 | 《Shiro开发详细教程》第四章:Shiro中Ini配置

之前章节我们已经接触过一些 INI 配置规则了,如果大家使用过如 Spring 之类的 IOC/DI 容器的话,Shiro 提供的 INI 配置也是非常类似的,...

21720

扫码关注云+社区

领取腾讯云代金券