在Java并发编程中,阻塞队列(BlockingQueue)是一个非常有用的工具。它是一个线程安全的队列,支持生产者-消费者模式,可以解决多线程并发访问的问题。本文将详细介绍阻塞队列的基本概念、实现原理、使用场景以及注意事项。
5.7 Queue并发集合 之前,我们介绍了Queue队列。对于队列的相关知识,你应该有了一个大概的了解! 在本篇中,我们会继续深入学习,来了解下线程安全的队列集合! 在Java多线程编程中,生产者消费者模型,想必大家都在熟悉不过了,简单来说就是一部分线程负责向容器中生产,而另一部分线程负责从容器中获取。 在这个模型当中,Java主要利用队列的数据结构进行实现。为了保证数据的安全,Java提供了两种线程安全的Queue队列,分为阻塞队列和非阻塞队列(并发队列)。 其中,阻塞队列典型的实现类是Blocking
在多线程编程中,经常需要使用线程安全的数据结构,用于在不同线程之间进行数据交换和通信。Java提供了一种称为阻塞队列(BlockingQueue)的数据结构,它是线程安全的队列实现,提供了一些特殊的方法来处理多线程环境下的数据交换问题。本文将介绍阻塞队列的基本概念和在Java中使用的三种常见方法:put,add和offer。
通过前面文章的学习,我们对Java中常用队列做了介绍。本文,咱们来对队列做个总结吧。
阻塞队列与普通队列的不同在于。当队列是空的时候,从队列中获取元素的操作将会被阻塞,或者当队列满时,往队列里面添加元素将会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:
个参数 : BlockingQueue<Runnable> workQueue ;
Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable、Vector),也讨论了并发容器(ConcurrentHashMap、CopyOnWriteArrayList),这些工具都为我们编写多线程程序提供了很大的方便。今天我们来讨论另外一类容器:阻塞队列。 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了Dequeue接口)。 使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产
大家都有使用过分布式消息队列,比如 ActiveMQ、 kafka、RabbitMQ 等等,消息队列的是有可以使得程序之 间实现解耦,提升程序响应的效率。 如果我们把多线程环境比作是分布式的话,那么线程与线 程之间是不是也可以使用这种消息队列的方式进行数据通 信和解耦呢?
在前面的系列文章中,我们介绍了一下 Java 中多线程的一些主要的知识点和多线程并发程序的设计和处理思想。包括线程的介绍、生命周期、线程的运行控制。之后介绍了如何确保 Java 多线程并发程序的正确性,即通过锁(ReentrantLock 、synchronized )的思想来实现多线程执行顺序的控制等。如果你对这些还不熟悉,建议看一下前面的文章。接下来我们来看一下 Java 多线程中另一个重要的知识:线程池,在此之前,我们需要了解一下 Java 中的阻塞队列:
并发编程之阻塞队列 1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQue
阻塞队列在多种业务场景中都非常有用,特别是在需要实现生产者-消费者模式、任务调度、线程池等情况下。
Java 5 之前实现同步存取时,可以使用普通的一个集合,然后在使用线程的协作和线程同步可以实现生产者,消费者模式,主要的技术就是用好 wait ,notify,notifyAll,sychronized 这些关键字。
在上一篇我们对Java中的队列分类做了简单的介绍。本文咱们主要来聊聊阻塞队列中的七个常用子类。这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个队列进行总结。最后在来个大总结。文章可能有点长,但是,大家耐着性子看完,保证你对这七大阻塞队列有深刻的理解。
在之前的《并发编程踩坑实录一:盘点JDK中同步容器的两大坑!!》一文中,我们主要一起学习了JDK中同步容器的两个坑,一个是在使用同步容器时可能会出现 竞态条件 的问题,一个是在使用同步容器时用 迭代器遍历容器 可能会踩坑。
使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦。但是有了阻塞队列就不一样了,它会对当前线程产生阻塞,比如一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞直到阻塞队列中有了元素。当队列中有元素后,被阻塞的线程会自动被唤醒(不需要我们编写代码去唤醒)。这样提供了极大的方便性。
生产者消费者模式最核心的部分是生产者与消费者之间的特殊容器,而阻塞队列是特殊容器最常见的实现。JDK中定义了阻塞队列接口BlockingQueue,JDK通过该接口为我们提供了很多种阻塞队列的实现,其中包括本节的主角ArrayBlockingQueue,该类位于java.util.concurrent.ArrayBlockingQueue.java。该类需要实现的核心方法如下,下面我们详细分析ArrayBlockingQueue的实现原理。
在上一篇《并发编程踩坑实录一:盘点JDK中同步容器的两大坑!!》中,我们主要一起学习了JDK中同步容器的两个坑,一个是在使用同步容器时可能会出现 竞态条件 的问题,一个是在使用同步容器时用 迭代器遍历容器 可能会踩坑。
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法.
队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除;比如我们常用的 LinkedList 集合,它实现了Queue 接口,因此,我们可以理解为 LinkedList 就是一个队列;
Java多线程详解【面试+工作】 Java线程:新特征-信号量 Java的信号量实际上是一个功能完毕的计数器,对控制一定资源的消费与回收有着很重要的意义,信号量常常用于多线程的代码中,并能监控有多少数目的线程等待获取资源,并且通过信号量可以得知可用资源的数目等等,这里总是在强调“数目”二字,但不能指出来有哪些在等待,哪些资源可用。 因此,本人认为,这个信号量类如果能返回数目,还能知道哪些对象在等待,哪些资源可使用,就非常完美了,仅仅拿到这些概括性的数字,对精确控制意义不是很大。目前还没想到更好的用法。 下面
BlockingQueue是一个接口,JDK提供了多种阻塞队列的实现方式。我们先看一下这个接口规定了哪些方法。
ConcurrentHashMap由Segment数组结构和HashEntry数组结构组成,Segement是一种可重入锁,在ConcurrentHashMap扮演着锁的角色;HashEntry用于存储键值对数据,一个ConcurrentHashMap中包含一个Segment数组,它是数组和链表结构。一个Segment里包含一个HashEntry数组,当对HashEntry数组进行修改操作时必须要获取它对应的Segment锁。
上次我们讲了一些常用的4个阻塞队列,但是在JDK中还提供了其他的一些阻塞队列。这篇文章将全面介绍一下JDK中的所有阻塞队列,并比较他们的区别。 JDK7提供了7个阻塞队列。分别是 ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。 LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。 PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。 DelayQueue:一个使用优先级队列实现的无界阻塞队列。 Syn
Queue 接口与 List、Set 同一级别,都是继承了 Collection 接口。LinkedList 实现了 Deque接口。
我们常用 obj.wait(),obj.notify() 或 obj.notifyAll() 来实现生产者-消费者, 不过它们是基于对象监视器锁的。
无界阻塞队列永远不满,put和offer方法永远不阻塞,offer永远返回true
在上一篇《亿级流量高并发秒杀系统商品“超卖”了,只因使用的JDK同步容器中存在这两个巨大的坑!!(踩坑实录,建议收藏)》中,我们主要一起学习了JDK中同步容器的两个坑,一个是在使用同步容器时可能会出现 竞态条件 的问题,一个是在使用同步容器时用 迭代器遍历容器 可能会踩坑。
这周刚上班突然有一个项目内存溢出了,排查了半天终于找到问题所在,在此记录下,防止后面再次出现类似的情况。
blog.csdn.net/u014454538/article/details/96910729
【1】阻塞队列:从定义上来说是队列的一种,那么肯定是一个先进先出(FIFO)的数据结构。与普通队列不同的是,它支持两个附加操作,即阻塞添加和阻塞删除方法。
可以看出,无任务执行时,线程池其实是利用阻塞队列的take方法挂起,从而维持核心线程的存活
BlockingQueue 是Java标准库中提供的 阻塞队列,底层是由链表、数组实现的,
【1】阻塞队列的架构图:阻塞队列与 List 具有很多类似之处,对比着学习会更加容易一些。
| 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand i
本节,我们来探讨Java并发包中的各种队列。Java并发包提供了丰富的队列类,可以简单分为: 无锁非阻塞并发队列:ConcurrentLinkedQueue和ConcurrentLinkedDeque 普通阻塞队列:基于数组的ArrayBlockingQueue,基于链表的LinkedBlockingQueue和LinkedBlockingDeque 优先级阻塞队列:PriorityBlockingQueue 延时阻塞队列:DelayQueue 其他阻塞队列:SynchronousQueue和LinkedT
在之前的文章Java中executors提供的的4种线程池中,学习了一下Executors类中提供的四种线程池.
LinkedBlockingQueue:按照先进先出的原则,可以不设置初始大小,不设置,默认就会Integer.MAX_VALUE
作者: Ruthless 关注 - 28 粉丝 - 2969 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 注:什么叫线程安全?这个首先要明确。线程安全就是说多线程访问同一代码,不会产生不确定的结果。 并行和并发区别
Java 提供的线程安全的 Queue 可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是 BlockingQueue,非阻塞队列的典型例子是 ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。阻塞队列可以通过加锁来实现,非阻塞队列可以通过 CAS 操作实现。
在【并发系列】中,主要讲解了 执行者与线程池,同步工具,锁 , 在分析源码时,或多或少的提及到了「队列」,队列在 JUC 中也是多种多样存在,所以本文就以「远看」视角,帮助大家快速了解与区分这些看似「杂乱」的队列
上篇文章我们介绍了队列的基类接口Queue它定义了所有实现队列的类必须拥有的方法行为而BlockingQueue阻塞队列接口继承了Queue接口,此外BlockingQueue队列接口是Java并发包里面所有实现线程安全队列的基类接口。
阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满;当队列空时,队列会阻塞获得元素的线程,直到队列变非空。阻塞队列就是生产者用来存放元素、消费者用来获取元素的容器。
> 公众号:[Java小咖秀](https://t.1yb.co/jwkk),网站:[javaxks.com](https://www.javaxks.com)
BlockingQueue 对插入操作、移除操作、获取元素操作提供了四种不同的方法用于不同的场景中使用:
不知不觉树义已经工作 5 年了,一路走来磕磕碰碰但总算有了自己的一点小体会。对于一个 Java 开发人员来说,到了 5 年的关键节点,需要掌握哪些知识点呢?经过我自己的总结,我列出了下面的思维导图。
2. 具体的场景,如果corePoolSize为x,maximumPoolSize为y,阻塞队列为z,第w个任务进来如何分配?
不知不觉已经工作 5 年了,一路走来磕磕碰碰但总算有了自己的一点小体会。对于一个 Java 开发人员来说,到了 5 年的关键节点,需要掌握哪些知识点呢?经过我自己的总结,我列出了下面的思维导图。
一共100个线程,核心线程数为4,最大线程数为5,空闲存活时间为0,阻塞队列为 4
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:
阻塞队列,也就是 BlockingQueue,它是一个接口。BlockingQueue是基于阻塞机制实现的线程安全的队列。而阻塞机制的实现是通过在入队和出队时加锁的方式避免并发操作。
领取专属 10元无门槛券
手把手带您无忧上云