SynchronousQueue详解

SynchronousQueue介绍

【1】SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take。

【2】如图所示,SynchronousQueue 最大的不同之处在于,它的容量为 0,所以没有一个地方来暂存元素,导致每次取数据都要先阻塞,直到有数据被放入;同理,每次放数据的时候也会阻塞,直到有消费者来取。

【3】需要注意的是,SynchronousQueue 的容量不是 1 而是 0,因为 SynchronousQueue 不需要去持有元素,它所做的就是直接传递(direct handoff)。由于每当需要传递的时候,SynchronousQueue 会把元素直接从生产者传给消费者,在此期间并不需要做存储,所以如果运用得当,它的效率是很高的。

SynchronousQueue的源码分析

【1】构造函数

【2】核心方法分析

【1】Transferer是SynchronousQueue的内部抽象类,双栈和双队列算法共享该类。他只有一个transfer方法,用于转移元素,从生产者转移到消费者;或者消费者调用该方法从生产者取数据。

【2】Transferer有两个实现类:TransferQueue和TransferStack。

【3】这两个类的区别就在于是否公平。TransferQueue是公平的,TransferStack非公平。

【4】源码展示

【1】节点元素

【2】构造方法

【3】核心方法

【1】节点元素

【2】核心方法

SynchronousQueue总结

【1】是一个没有数据缓冲的BlockingQueue,容量为0,它不会为队列中元素维护存储空间,它只是多个线程之间数据交换的媒介。

【2】数据结构:链表,在其内部类中维护了数据

先消费(take),后生产(put);

第一个线程Thread0是消费者访问,此时队列为空,则入队(创建Node结点并赋值)

第二个线程Thread1也是消费者访问,与队尾模式相同,继续入队

第三个线程Thread2是生产者,携带了数据e,与队尾模式不同,不进行入队操作。直接将该线程携带的数据e返回给队首的消费者,并唤醒队首线程Thread1(默认非公平策略是栈结构),出队。

反之,先生产(put)后消费(take),原理一样

【3】锁:CAS+自旋(无锁)【阻塞:自旋了一定次数后调用 LockSupport.park()】

【4】存取调用同一个方法:transfer()

put、offer 为生产者,携带了数据 e,为 Data 模式,设置到 SNode或QNode 属性中。

take、poll 为消费者,不携帯数据,为 Request 模式,设置到 SNode或QNode属性中。

【5】过程

线程访问阻塞队列,先判断队尾节点或者栈顶节点的 Node 与当前入队模式是否相同

相同则构造节点 Node 入队,并阻塞当前线程,元素 e 和线程赋值给 Node 属性

不同则将元素 e(不为 null) 返回给取数据线程,队首或栈顶线程被唤醒,出队

【6】公平模式:TransferQueue,队尾匹配(判断模式),队头出队,先进先出

【7】非公平模式(默认策略):TransferStack,栈顶匹配,栈顶出栈,后进先出

【8】应用场景

SynchronousQueue非常适合传递性场景做交换工作,生产者的线程和消费者的线程同步传递某些信息、事件或者任务。

SynchronousQueue的一个使用场景是在线程池里。如果我们不确定来自生产者请求数量,但是这些请求需要很快的处理掉,那么配合SynchronousQueue为每个生产者请求分配一个消费线程是处理效率最高的办法。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。

Original: https://www.cnblogs.com/chafry/p/16782932.html
Author: 忧愁的chafry
Title: SynchronousQueue详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/711744/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL中的事务和MVCC

    本篇博客参考掘金小册——MySQL 是怎样运行的:从根儿上理解 MySQL 以及极客时间——MySQL实战45讲。 虽然我们不是DBA,可能对数据库没那么了解,但是对于数据库中的索…

    技术杂谈 2023年7月25日
    098
  • jq命令用法总结

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 如果说要给Linux文本三剑客(grep、sed、awk)添加一员的话,我觉得应该是jq命令,因为j…

    技术杂谈 2023年7月24日
    0101
  • 【转】再谈自研开源Kube-OVN, 设计思路及实现原理

    原文:https://cloud.tencent.com/developer/article/1475917 Original: https://www.cnblogs.com/o…

    技术杂谈 2023年5月30日
    0134
  • Go学习第二天:查看变量的类型

    方法一: %T 格式化输出%T。详情见这个例子: import "fmt" func main(){ var a = 1 fmt.Printf( "a…

    技术杂谈 2023年7月24日
    0101
  • PDF转换OFD(Java实用版)

    前言: 在项目中用到了,就写一下哈 OFD简介 百度百科:https://baike.baidu.com/item/OFD/56227163?fr=aladdin OFD(Open…

    技术杂谈 2023年6月21日
    0112
  • kettle插入更新

    kettle实现若主键存在则更新,若主键不存在则插入 Original: https://www.cnblogs.com/cheng9999/p/14085922.htmlAuth…

    技术杂谈 2023年7月24日
    094
  • 设计模式——结构性设计模式

    结构性设计模式 针对类与对象的组织结构。(白话:类与对象之间的交互的多种模式 类/对象适配器模式 当需要传入一个A类型参数,但只有B类型类时,就需要一个A类型的适配器装入B类的数据…

    技术杂谈 2023年7月11日
    0106
  • AI工程师的笔记本环境配置

    还是爱折腾… 前一阵子买了个新的笔记本电脑, 幻13-3050TI-1T版本,全能本,CPU是8核心16线程的标压版AMD锐龙9-5900HS,显卡是NVIDIA-30…

    技术杂谈 2023年7月10日
    0104
  • Kaldi 语音识别基础教程

    Kaldi 介绍 Kaldi 是由 C++ 编写的语音识别工具,其目的在于为语音识别研究者提供一个研究和使用的平台。 Kaldi 环境搭建 本文主要通过使用 Docker 和 Nv…

    技术杂谈 2023年5月30日
    097
  • 【LEETCODE】74、第542.题 01 矩阵

    package array.medium; import java.util.ArrayDeque; import java.util.Deque; import java.uti…

    技术杂谈 2023年7月24日
    091
  • C++ 回调函数及 std::function 与 std::bind

    回调函数是做为参数传递的一种函数,在早期C样式编程当中,回调函数必须依赖函数指针来实现。 而后的C++语言当中,又引入了 std::function 与 std::bind 来配合…

    技术杂谈 2023年6月21日
    0115
  • Reactor模型

    要无障碍阅读本文,需要对NIO有一个大概的了解,起码要可以写一个NIO的Hello World。 说到NIO、Netty,Reactor模型一定是绕不开的,因为这种模式架构太经典了…

    技术杂谈 2023年7月25日
    073
  • 正投影与斜投影

    正投影 设物体上任一点的三维坐标为(p(x,y,z)),投影后的三维坐标为(p^,(x^,,y^,,z^,)),则正交投影方程为: [ \left{\begin{array}{rc…

    技术杂谈 2023年7月11日
    0135
  • WCF 返回json的时间格式的转换

    有朋友用这个办法不错 1、把”\/Date(976723200000+0800)\/”中的976723200000提取出来,这一步无论是正则还是substr…

    技术杂谈 2023年7月11日
    0106
  • Zalenium使用

    zalenium是一种以容器方式来动态创建和管理本地Selenium Grid的扩展。它使用docker-selenium在本地运行基于Firefox和Chrome的测试。 1、安…

    技术杂谈 2023年5月31日
    088
  • 20212218实验二《Python程序设计》实验报告

    # 20212218 2021-2022-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级: 2122 姓名: 林思凡 学号:20212218 实验教师…

    技术杂谈 2023年7月24日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球