java 同步 数据结构_Java同步数据结构之SynchronousQueue

前言

严格来说SynchronousQueue并不是像它的名字那样是一种Queue,它更像是一个数据接力的交汇点,还记得在介绍Exchanger的时候提到过Exchanger可以看作是SynchronousQueue的双向形式吗,Exchanger是一种可以同时容纳多对线程进行两两交换数据的场所,所以Exchanger的重点是交换(双向)数据,而SynchronousQueue只是一方将自己的数据交给另一方,并不会接收来自另一方的数据,即SynchronousQueue是对数据的一种单向传递,所以Exchanger可用看着是SynchronousQueue的双向形式。

虽然Exchanger与SynchronousQueue有这种相识性,但是它们两者的实现是完全不同的,只是最终达到的效果有这种类比性而已。Exchanger的实现是通过一个长度在约束的最大范围内不断伸缩的数组来存储一方的数据,当另一方到来时,通过将其映射到特定数组下标来实现数据交换或等待,当然这只是最简单的思想。SynchronousQueue的实现分别针对公平/非公平性的支持采用双队列/双堆栈来实现数据存储,虽然采用的数据结构不同,但是中心思想还是非常类似的:当相同类型的线程(都是数据提供方或者数据接收者)到来时都将它们排队进入队列/堆栈,当与队列/堆栈中头节点互补线程(一方是数据提供者,另一方是数据接收者)到来时,就完成数据传递,然后它们双双出队返回。

SynchronousQueue的设计目得主要就是阻塞每一个操作,直到与其互补的操作出现,才完成数据交接返回。例如,当一个线程执行put(提供数据的生产者)操作,如果队列/堆栈中最近一次入队的操作是take(请求数据的消费者),这时候它们形成互补,那么它们进行数据交接,双双出队并返回;如果队列/堆栈为空或最近一次入队的操作也是put操作,那么当前线程只能入队等待,反之亦然。当然SynchronousQueue同时也提供了相应的非阻塞以及指定超时时间的互补操作 offer/poll,它们在执行的时候或在指定的超时时间内,如果没有出现与其互补的操作则立即返回,例如,一个线程执行无超时时间的offer操作,这时候如果队列/堆栈中不存在与其互补的操作 poll或take,那么它将立即出队返回,而不是像put的那样非要等到一个与其互补的操作出现拿走它的数据,反之亦然。

由此可见SynchronousQueue其实是一种阻塞队列,实际上SynchronousQueue虽然也是集合框架的实现类,但是它并没有容量,即size返回0,isEmpty返回true,所有Collection的相关方法(包括迭代器)都将把SynchronousQueue当成一个空队列处理,因为只有存在互补操作的瞬间,才会发生数据的交接,这时候才可以说存在数据,其它时候都是无意义的。在SynchronousQueue的实现中,将这种互补操作的数据交接过程称之为“fulfill”,正在交接称之为“fulfilling”,还没有开始交接为“unfulfilled”,交接完成为“fulfilled”,了解这些对源码的了解将容易的多。

标签:队列,Java,SynchronousQueue,互补,线程,Exchanger,数据结构,数据

来源: https://www.cnblogs.com/txmfz/p/10346856.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值