如何在数据结构中同步插入/删除元素,功能方式?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在数据结构中同步插入/删除元素,功能方式?相关的知识,希望对你有一定的参考价值。

我有一个数据结构,比如MinHeap。它有像peek(),removeElement()和addElement()这样的方法。 removeElement()addElement()如果不是线程安全的话会产生不一致的状态(因为它们涉及增加/减少currentHeapSize)。 现在,我想实现这种数据结构,功能方式。我已经读过,在函数式编程中,不可变性是导致线程安全的关键。我如何在这里实现?我应该避免递增/递减currentHeapSize吗?如果是这样,怎么样?我想对此有所指导。

编辑#1 @YuvalItzchakov和@Dima已经指出我每次进行插入/删除时都需要返回一个新的集合,这是有道理的。但这不会严重妨碍表演吗?我的用例是我将获得一个数据流,并继续将其添加到堆中。当有人请求数据时,返回最小堆的根。所以这里插入非常迅速。不会为每个插件创建一个新的堆证明是昂贵的吗?我想会的。如果是这样,函数式编程如何真正起作用?它只是一个理论概念还是具有实际意义?

答案

并行访问相同数据结构的问题是双重的。首先,我们需要序列化并行更新。 @Tim给出了一个全面的答案。其次,在有许多读者的情况下,我们可能希望允许他们与写作并行阅读。在这种情况下,不变性发挥其作用。没有它,作家必须等待读者完成。

另一答案

实际上没有一种“功能”方法可以让多个线程更新数据结构。事实上,在多线程环境中函数式编程如此优秀的一个原因是因为没有像这样的任何共享数据结构。

但是在现实世界中,这个问题一直存在,所以你需要一些方法来序列化对共享数据结构的访问。最粗略的方法就是在整个代码周围放置一个大锁,只允许一个线程同时运行(例如使用Mutex)。通过巧妙的设计,可以使其合理有效,但维护起来可能很困难。

更复杂的方法是为您的数据结构提供一个线程安全的请求队列,以及一个一个一个地处理这些请求的工作线程。一个支持这种模式的流行框架是Akka Actors。将数据结构包装在Actor中,然后接收读取或修改数据结构的请求。 Akka框架将确保一次只处理一条消息。

在您的情况下,您的actor将管理堆并从流中接收将进入堆的更新。然后,其他线程可以按顺序,线程安全的方式发出将成为进程的请求。最好是这些请求在堆上执行特定查询,而不是每次都返回整个堆。

另一答案

你可以使用猫Ref类class https://typelevel.org/cats-effect/concurrency/ref.html但是它是AtomicReference的实现,还是写一些java.util.concurent.ConcurentHashMap包装器

以上是关于如何在数据结构中同步插入/删除元素,功能方式?的主要内容,如果未能解决你的问题,请参考以下文章

jquery怎么在一个元素之前插入元素

同步框架:如何在中心辐射模型中启用批量插入/更新/删除存储过程

数据结构队列及其Java代码实现

HTML - 如何以前置方式插入行?

sql如何将两个表里的数据同步?

D3.js 入门系列 --- 2.1 关于如何选择,插入,删除元素