Java中的阻塞队列(2)

简介: 6、同步队列SynchronousQueue    同步队列是一个不存储元素的阻塞队列,每一个put操作必须等待一个take操作,否则就不能继续添加元素。

6、同步队列SynchronousQueue

    同步队列是一个不存储元素的阻塞队列,每一个put操作必须等待一个take操作,否则就不能继续添加元素。这种场景下可用于多个线程之间的通讯,a线程可以把需要传递的数据放到同步队列中,b线程消费队列中的数据,因为本身不存储元素,所以SynchronousQueue的吞吐量高于ArrayBlockingQueue和LinkedBlockingQueue

    首先看一下结构,从结构上跟别的队列并没有什么太大的区别,所以区别就要看里面的源码了

img_8291605a29e71c4c6eada8feb7ff4478.png
图6-1

    SynchronousQueue队列分为两种模式默认采取的非公平锁,SynchronousQueue不存储元素,所以会有很多的生产者和消费者阻塞,对于这些阻塞的线程,非公平锁中存入了一个LIFO队列中,其实就是把线程放入队列,而不是数据

    当SynchronousQueue构造函数中入口参数改为true,此时队列采取公平锁,阻塞的线程存入一个FIFO队列中

    此处具一个例子

img_a956ea47095083262ddaf3ea9ac6e7bc.png
图6-2
img_675f752914e2a54bf31e50d24a6b6973.png
图6-3

7、LinkedBlockingDeque链表双向阻塞队列

    由链表结构组成的双向阻塞队列,双向队列指的是可以从队列的两端插入和移出元素

8、链表传输队列LinkedTransferQueue

    这个需要重点说一下,首先看一下类组成结构如图8-1

img_5468e2b2b5e26e41744117f5c530221c.png
图8-1

    此处我们单独拿出TransferQueue接口所扩展的方法来看这个传输队列的作用,如图8-2

img_7e90f7605164759d0e03f2924e48675d.png
图8-2

        我们可以看到TransferQueue接口扩展的几个方法:

            1、transfer(E e) :如果目前有消费者阻塞,则直接移交消费者,如果没有,放到队列尾部且生产者进入阻塞,直到数据被消费

            2、tryTransfer(E e):如果目前有消费者阻塞,则直接移交消费者,如果没有,直接返回false,而且数据不进入队列,这个操作不会阻塞线程

            3、tryTransfer(E e,long timeOut,TimeUnit unit):如果目前有消费者阻塞,则直接移交消费者,如果没有,放到队列尾部且生产者进入阻塞,等到消费者来消费,如果指定时间中无法被消费者获取,则直接返回false,同时元素被移除

            4、hasWaitingConsumer():判断有没有等待的消费者

            5、getWaitingConsumerCount():获取目前存在的消费者的数量

    知道了这些,基本就能大概了解到这个实现TransferQueue接口的类大多能做什么了,接下来直接上一个简单的应用

    如图8-3

img_46654208f09cc192e9a45b601d31e856.png
图8-3
img_b6b27858b88fc638d25fa57bf425ae9a.png
图8-4
img_b554c35c3d0ee468c807cb101ec5df3e.png
图8-5
相关文章
|
8月前
|
存储 安全 Java
Java线程池ThreadPoolExcutor源码解读详解02-阻塞队列之ArrayBlockingQueue
`ArrayBlockingQueue` 是Java中一个基于数组的并发队列,具有线程安全的性质。以下是其关键信息的摘要: - **继承实现关系**:它扩展了`AbstractQueue`并实现了`BlockingQueue`接口,确保线程安全的入队和出队操作。 - **数据结构**:内部由固定大小的数组支撑,有`takeIndex`和`putIndex`跟踪元素的添加和移除位置,`count`记录队列中的元素数量。 - **特点**:队列长度在创建时必须指定且不可变,遵循先进先出(FIFO)原则,当队列满时,添加元素会阻塞,空时,移除元素会阻塞。
90 0
|
5月前
|
存储 监控 安全
一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这篇文章是Java面试第三天的笔记,讨论了线程安全、Thread与Runnable的区别、守护线程、ThreadLocal原理及内存泄漏问题、并发并行串行的概念、并发三大特性、线程池的使用原因和解释、线程池处理流程,以及线程池中阻塞队列的作用和设计考虑。
|
5月前
|
存储 安全 Java
从基础到实战:如何用 Java 手写一个阻塞队列?
大家好,我是小米!今天分享手写阻塞队列(Blocking Queue)教程,深入讲解并发编程中的 wait() 和 notifyAll() 机制,通过代码实战,让你轻松掌握生产者-消费者模型中的阻塞队列实现!
130 0
|
7月前
|
存储 Java API
java线程之阻塞队列
java线程之阻塞队列
|
7月前
|
存储 缓存 Java
Java 中的阻塞队列
Java 中的阻塞队列
34 0
|
8月前
|
存储 安全 Java
Java多线程基础-9:代码案例之阻塞队列(二)
Java多线程基础教程系列中,介绍了如何实现一个简单的阻塞队列(非泛型版本)。
72 0
|
8月前
|
消息中间件 存储 负载均衡
Java多线程基础-9:代码案例之阻塞队列(一)
阻塞队列是一种遵循先进先出原则的线程安全数据结构,它在队列满时会阻塞入队操作,队列空时会阻塞出队操作,常用于多线程间的协作,简化同步代码编写。Java中提供了`BlockingQueue`接口及其实现类,如`ArrayBlockingQueue`和`LinkedBlockingQueue`,用于实现生产者-消费者模型,以实现负载均衡和资源的有效利用,如削峰填谷,降低系统压力。
91 0
|
8月前
|
存储 安全 Java
Java线程池ThreadPoolExcutor源码解读详解08-阻塞队列之LinkedBlockingDeque
**摘要:** 本文分析了Java中的LinkedBlockingDeque,它是一个基于链表实现的双端阻塞队列,具有并发安全性。LinkedBlockingDeque可以作为有界队列使用,容量由构造函数指定,默认为Integer.MAX_VALUE。队列操作包括在头部和尾部的插入与删除,这些操作由锁和Condition来保证线程安全。例如,`linkFirst()`和`linkLast()`用于在队首和队尾插入元素,而`unlinkFirst()`和`unlinkLast()`则用于删除首尾元素。队列的插入和删除方法根据队列是否满或空,可能会阻塞或唤醒等待的线程,这些操作通过`notFul
329 5
|
8月前
|
存储 安全 Java
Java线程池ThreadPoolExcutor源码解读详解07-阻塞队列之LinkedTransferQueue
`LinkedTransferQueue`是一个基于链表结构的无界并发队列,实现了`TransferQueue`接口,它使用预占模式来协调生产者和消费者的交互。队列中的元素分为数据节点(isData为true)和请求节点(isData为false)。在不同情况下,队列提供四种操作模式:NOW(立即返回,不阻塞),ASYNC(异步,不阻塞,但后续线程可能阻塞),SYNC(同步,阻塞直到匹配),TIMED(超时等待,可能返回)。 `xfer`方法是队列的核心,它处理元素的转移过程。方法内部通过循环和CAS(Compare And Swap)操作来确保线程安全,同时避免锁的使用以提高性能。当找到匹
303 5
|
8月前
|
存储 缓存 Java
Java线程池ThreadPoolExcutor源码解读详解06-阻塞队列之SynchronousQueue
SynchronousQueue 是 Java 中的一个特殊阻塞队列,它没有容量,实现线程间的直接对象交换。这个队列的特点和优缺点如下: 1. **无容量限制**:SynchronousQueue 不存储任何元素,每个 put 操作必须等待一个 take 操作,反之亦然。这意味着生产者和消费者必须严格同步。 2. **阻塞性质**:当一个线程试图插入元素时,如果没有线程正在等待获取,那么插入操作会阻塞;同样,尝试获取元素的线程如果没有元素可取,也会被阻塞。 3. **公平与非公平策略**:SynchronousQueue 支持公平和非公平的线程调度策略。公平模式下,等待时间最长的线程优先
141 5