作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
一、SynchronousQueue简介
SynchronousQueue
是JDK1.5时,随着J.U.C包一起引入的一种阻塞队列,它实现了BlockingQueue接口,底层基于 栈 和 队列 实现:
没有看错,SynchronousQueue的底层实现包含两种数据结构—— 栈 和 队列 。这是一种非常特殊的阻塞队列,它的特点简要概括如下:
- 入队线程和出队线程必须一一匹配,否则任意先到达的线程会阻塞。比如ThreadA进行入队操作,在有其它线程执行出队操作之前,ThreadA会一直等待,反之亦然;
- SynchronousQueue内部不保存任何元素,也就是说它的容量为0,数据直接在配对的生产者和消费者线程之间传递,不会将数据缓冲到队列中。
- SynchronousQueue支持公平/非公平策略。其中非公平模式,基于内部数据结构——“栈”来实现,公平模式,基于内部数据结构——“队列”来实现;
- SynchronousQueue基于一种名为“Dual stack and Dual queue”的无锁算法实现。
注意:上述的特点1,和我们之前介绍的Exchanger其实非常相似,可以类比Exchanger的功能来理解。
二、SynchronousQueue原理
2.1 构造
之前提到,SynchronousQueue根据公平/非公平访问策略的不同,内部使用了两种不同的数据结构:栈和队列。我们先来看下对象的构造,SynchronousQueue只有2种构造器:
/**
* 默认构造器.
* 默认使用非公平策略.
*/
public SynchronousQueue() {
this(false);
}
/**
* 指定策略的构造器.
*/
public SynchronousQueue(boolean fair) {
transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
可以看到,对于公平策略,内部构造了一个 TransferQueue 对象,而非公平策略则是构造了 TransferStack 对象。这两个类都继承了内部类 Transferer ,SynchronousQueue中的所有方法,其实都是委托调用了TransferQueue/TransferStack的方法:
public class SynchronousQueue<E> extends AbstractQueue<E>