java阻塞队列有哪些(java阻塞队列和非阻塞队列)

java阻塞队列有哪些(java阻塞队列和非阻塞队列)目录 一 什么是阻塞队列 二 阻塞队列种类分析 三 非阻塞队列 Java 提供的线程安全的 Queue 可以分为阻塞队列和非阻塞队列 其中阻塞队列的典型例子是 BlockingQueu 非阻塞队列的典型例子是 ConcurrentLi 在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列 nbsp nbsp nbsp nbsp amp

大家好,我是讯享网,很高兴认识大家。



目录

一、什么是阻塞队列

二、阻塞队列种类分析

三、非阻塞队列

Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。

        阻塞队列(BlockingQueue)首先是一个队列 ,也是一个支持两个附加操作的队列,这两个附加的操作支持阻塞的插入和移除方法。

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

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

        BlockingQueue提供的常用方法如下:

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

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

简单介绍下其中三个队列:

1、ArrayListBlockingQueue


讯享网

2、LinkedBlockingQueue

    LinkedBlockingQueue默认大小是Integer.MAX_VALUE,可以设定大小,可以理解为一个缓存的有界等待队列。
    基于链表的阻塞队列,内部维持着一个数据缓冲队列(该队列由链表构成)。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。
    LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

3、SynchronousQueue

基于锁的算法会带来一些活跃度失败的风险。如果线程在持有锁的时候因为阻塞I/O,页面错误,或其他原因发生延迟,很可能所有的线程都不能前进了。 一个线程的失败或挂起不应该影响其他线程的失败或挂起,这样的算法成为非阻塞(nonblocking)算法;如果算法的每一个步骤中都有一些线程能够继续执行,那么这样的算法称为锁自由(lock-free)算法。在线程间使用CAS进行协调,这样的算法如果能构建正确的话,它既是非阻塞的,又是锁自由的。非竞争的CAS总是能够成功,如果多个线程以一个CAS竞争,总会有一个胜出并前进。

非阻塞算法通过使用低层次的并发原语,比如比较交换,取代了锁。原子变量类向用户提供了这些底层级原语,也能够当做“更佳的volatile变量”使用,同时提供了整数类和对象引用的原子化更新操作。

作者:程序员龙猫

        基于链接节点的、无界的、线程安全。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列检索操作从队列头部获得元素。当许多线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许 null 元素。

        入队和出队操作均利用CAS(compare and set)更新,这样允许多个线程并发执行,并且不会因为加锁而阻塞线程,使得并发性能更好。

        在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量地避免程序出现意外的错误。阻塞队列使用最经典的场景就是socket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。还有其他类似的场景,只要符合生产者-消费者模型的都可以使用阻塞队列。

        使用非阻塞队列,虽然能即时返回结果(消费结果),但必须自行编码解决返回为空的情况处理(以及消费重试等问题)。

        另外他们都是线程安全的,不用考虑线程同步问题。

小讯
上一篇 2025-04-16 18:04
下一篇 2025-05-28 15:05

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/183149.html