阻塞队列(BolckingQueue)
一、插入与移除
1、插入
队列不满时可执行插入元素线程,直到队列满。
2、移除
队列不为空时都可移除,直到队列为空。
抛出异常:满的时候插入,空的时候取出都会抛出异常。
返回特殊值:插入成功返回true
一直阻塞:满时put和空时take会阻塞线程,直到队列可用。
二、JDK7提供了7个阻塞队列:
1、ArrayListBlockingQueue
ArrayBlockingQueue是一个由数组支持的有界阻塞队列。在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。
2、LinkedBlockingQueue
一个由链表结构组成的双向阻塞队列。
基于链表的阻塞队列,内部维持着数据缓冲队列。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;当队列缓冲区达到最大缓冲容量时,才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生成者线程才会被唤醒,反之对消费者的处理也基于同样的原理。
LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者和消费者分别采用了独立的锁来控制数据同步,也就意味着在高并发的情况下生产者和消费者可以并行的操作队列中的数据,以此来提高整个队列的并发性能。
3、SynchronousQueue
一个不存储元素的阻塞队列,在某次添加元素后必须等待其他线程取走后才能继续添加。
4、 PriorityBlockingQueue
是一个带优先级的队列,而不是先进先出队列,该队列也没有上限,但是如果队列为空,那么取元素的操作take就会阻塞。
5、DelayQueue
是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。
三、ArrayListBlockingQueue和LinkedBlockingQueue的区别?
1、队列中锁的实现不同
ArrayBlockingQueue生产者消费者使用同一个锁。
LinkedBlockingQueue生产用的是putLock,消费是takeLock。
2、在生产和消费时操作不同
ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为节点进行插入或移除,会影响性能。
3、 队列大小初始化方式不同
ArrayBlockingQueue实现的队列必须指定大小
LinkedBlockingQueue可以不指定大小,默认是Integer.MAX_VALUE
ArrayBlockingQueue性能要比LinkedBlockingQueue性能要好,执行速度更快,ArrayBlockingQueue优先使用!
非阻塞队列
ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部;当我们获取一个元素时,它会返回队列头部的元素。
入队和出队都采用CAS(compare and set)更新,这样允许多个线程并发执行,并且不会因为加锁而阻塞线程,使得并发性能更好。
注:CAS用于实现多线程同步的原子指令,它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。
代码实例
package OSChina.Client;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BlockingQueueTest {
static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
//定义装苹果的篮子
public static class Basket{
// 篮子,能够容纳3个苹果
static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);
//生产苹果,放入篮子
public void produce() throws InterruptedException{
queue.put("An apple");
}
// 消费苹果,从篮子中取走
public String consume() throws InterruptedException{
String apple = queue.take();
return apple;
# **最后**
**最后,强调几点:**
* 1\. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
* 2\. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
* 3\. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
> **以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。**
**如何获取整理好的Java面试专题资料?**
**[资料获取方式:点击这里免费下载](https://gitee.com/vip204888/java-p7)**
# **面试答案**


答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。**
**如何获取整理好的Java面试专题资料?**
**[资料获取方式:点击这里免费下载](https://gitee.com/vip204888/java-p7)**
# **面试答案**
[外链图片转存中...(img-H88twLDG-1628579368078)]
[外链图片转存中...(img-mOpH8fIR-1628579368081)]
