繁体   English   中英

用Java创建原子RingBuffer

[英]Creating an Atomic RingBuffer in Java

我在考虑如何在Java和Android中实现线程安全的RingBuffer(由于某些原因,即使经过了这么多年,也没有循环队列。因此,没有(Circular / Ring)ByteBuffer,也没有(Circular / Ring)(缓冲区/队列)。

甚至大多数第三方的RingBuffer实现都被认为不是线程安全的,这使我认为它确实不像我想的那样简单。 我在想的是在做这样的事情:

  • 有一个封装了Head和Tail位置的对象(例如RingBufferPosition)。
  • 让RingBuffer维护对RingBufferPosition的AtomicReference
  • 当一个线程添加一些东西时,它将创建一个临时的对象(不幸的是,我对Java的了解还不够多,但是要“堆栈分配”),该对象将被反复循环,并使用新的更新头进行更新直到它可以成功地CAS。
  • 当线程删除某些内容时,它将类似于添加某些内容。
  • 在分配给最大长度的数组中访问所有内容,因此,头和​​尾可以在O(1)时间内访问/更新当前元素。

这项工作会更好吗?与仅同步对集合的访问相比,它会带来任何好处吗?

一小段代码示例/伪代码(尚未运行,并且我什至不知道如何远程测试原子数据结构,我计划将其用于缓冲/流媒体,但是我还没有达到所需的距离首先创建)可以在此处找到。 我的评论/文档在那里详细说明了我的担忧。

最后,为了解决一个可能的“为什么”问题,例如“为什么需要这样的表现”,我将是真实的。 我一直发现数据结构,特别是无原子/无锁数据结构非常有趣,并且我发现这是一个非常好的学习练习,而且我一直想创建一个环形缓冲区。 我本可以使所有内容“同步”,但是我也很重视性能。

多个读取器/多个写入器环形缓冲区很棘手。

您的方法行不通,因为您无法原子地更新该开始/结束位置和数组内容。 考虑添加到缓冲区:如果首先更新结束位置,则在缓冲区包含无效项的情况下,需要一段时间才能更新数组。 如果您首先更新数组,那么没有什么可以阻止同时添加内容踩踏同一数组元素的。

有很多方法可以解决这些问题,但是各种方法都有不同的权衡取舍,并且如果您可以摆脱多读取器或多写入器的要求,则可以使用更好的选择。

如果我不得不猜测为什么在标准库中没有并发的环形缓冲区,那是因为没有一种最佳的实现方法对大多数情况都适用。 相比之下,用于ConcurrentLinkedQueue的数据结构简单而优雅,并且在需要并发链接列表时是显而易见的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM