SynchronousQueue 同步队列入门使用&源码详解
SynchronousQueue
文章插图
思维导图
是什么SynchronousQueue 是这样一种阻塞队列 , 其中每个 put 必须等待一个 take , 反之亦然 。
简而言之:线程安全 , 阻塞 。
入门案例我们定义两个线程 , 一个负责写入 , 一个负责读取 。
import java.util.concurrent.SynchronousQueue;import java.util.concurrent.TimeUnit;/** * @author 老马啸西风 * @since 1.0.0 */public class SynchronousQueueDemo {public static void main(String[] args) {SynchronousQueue
对应的日志信息如下:
开始设置第 0 个元素开始设置第 1 个元素读取信息: 0开始设置第 2 个元素读取信息: 1开始设置第 3 个元素读取信息: 2开始设置第 4 个元素读取信息: 3读取信息: 4
可以看到当元素被设置之后 , 就会被立刻读取 。 这个在实际使用过程中还是非常便利的 , 比轮训优雅多了 。
源码分析类定义public class SynchronousQueue
【SynchronousQueue 同步队列入门使用&源码详解】实现了阻塞队列接口 , 继承自 AbstractQueue 抽象队列 。
实际上对应的 put/take 方法 , 经过 transfer 的封装之后 , 都变得非常简单 。
我们本文的核心在于对 Transferer 的解析 。
构造器SynchronousQueue 也是支持是否为公平锁模式的 。
默认为非公平模式 。
是否公平取决于使用的 Transfer 实现子类 。
public SynchronousQueue() {this(false);}public SynchronousQueue(boolean fair) {transferer = fair ? new TransferQueue
put 方法/** * Adds the specified element to this queue, waiting if necessary for * another thread to receive it. */public void put(E e) throws InterruptedException {if (e == null) throw new NullPointerException();if (transferer.transfer(e, false, 0) == null) {Thread.interrupted();throw new InterruptedException();}}
take 方法/** * Retrieves and removes the head of this queue, waiting if necessary * for another thread to insert it. */public E take() throws InterruptedException {E e = transferer.transfer(null, false, 0);if (e != null)return e;Thread.interrupted();throw new InterruptedException();}
算法笔记下面是源码中的一部分算法笔记 , 不会出现在文档中 。
此类实现W. N. Scherer III和M. L. Scott所著的“不带条件同步的并发对象的无阻塞”中描述的双堆栈和双队列算法的扩展 。
第十八届年度大会 (2004年10月 , 分布式计算)(另请参见) 。
(Lifo)堆栈用于非公平模式 , (Fifo)队列用于公平模式 。
两者的性能通常相似 。
Fifo通常在竞争下支持更高的吞吐量 , 但是Lifo在常见应用程序中保持更高的线程局部性 。
双队列(和类似的堆栈)是在任何给定时间保存“数据”(由put操作提供的项 , 或“请求”)的插槽 , 表示 take 操作 , 或者为空 。
对 fulfill 的调用(即 , 从保存数据的队列中请求元素的调用 , 反之亦然)使互补节点出队 。
文章插图
互补节点
这些队列最有趣的功能是 , 任何操作都可以弄清楚队列所处的模式 , 并且无需锁就可以采取相应的措施 。
队列和堆栈都扩展了抽象类Transferer , 它们定义了执行放置或取出操作的单个方法 。
将它们统一为一个方法 , 因为在双重数据结构中 , 放置和取出操作是对称的 , 因此几乎所有代码都可以合并 。
最终的传输方法长远来看 , 但比分解成几乎重复的部分要容易得多 。
队列和堆栈数据结构在概念上有很多相似之处 , 但具体细节很少 。
为简单起见 , 它们保持不同 , 以便以后可以分别发展 。
- 新机|中兴公布全新渠道及市场策略,两款新机同步亮相
- 公安|共享位置文图同步声像同传!大连公安推出微信微博在线报警
- 太方便了!手机照片同步到电脑竟然这么简单,整理归类更轻松
- 摄像头|软硬件同步升级 2021年手机还能有什么新花样?
- 24问:一主多从的半同步复制,到底是哪个slave拖慢了性能
- 二十三、Python队列实现多线程(下篇)
- 揭秘|虾秘功能大揭秘之店铺同步&数据总览
- 越南|富士康计划部分生产线迁至越南,供应商或同步迁移,苹果布局多年
- 门店|新零售添生力军 绿叶购全国200家门店今日同步开业
- 升级|抢走华为订单!台积电2022年量产4nm芯片,苹果A16将同步升级