【问题标题】:Why doesn't exist not concurrent version of SkipList为什么不存在不并发版本的 SkipList
【发布时间】:2014-05-27 12:29:53
【问题描述】:

我开始研究 ConcurrentSkipListSet。

从一开始我就试图了解 SkipList 是什么?

我想是这样的(可能的变体):

我有两个问题:

  1. SkipList 与并发有何关系?
  2. 为什么不存在不 此数据结构的并发变体?

【问题讨论】:

  • 它是NavigableSet接口的一个实现——非线程安全的版本是TreeSet。
  • 树和我的照片 - 完全不同的结构

标签: java collections concurrency skip-lists


【解决方案1】:

您的跳过列表有点偏离,看起来更像:

来自http://en.wikipedia.org/wiki/File:Skip_list.svg

底部开始像一个链接列表,你已经明白了......但更多地将它们视为连接到每个级别的塔。这里的问题是,如果你想找到 7,你可以 skip 从 1 -> 4 -> 6 -> 9(哎呀,不),到 7。这​​可以让你近似平衡二叉树链表。

对于红黑树或 AVL 树,当需要修改结构时,必须将其完全锁定,以便重新排列结构。另一方面,跳过列表可以在没有全局锁的情况下“重新排列”。删除 7 只需要将指向它的链接更改为指向下一个元素,这只需要对 6 元素进行写锁定,而不是整个结构。

关于跳过列表的好读物是Skip Lists: A Probabilistic Alternative to Balanced Trees,它展示了它的工作原理和各种算法。这里面 是“表 2 - 不同算法的时序和实现”,它显示跳过列表的运行速度相当快,尽管其中一些是因为它们使用的特定数据。

在“跳过列表的附加工作”中

我已经描述了一组允许多个处理器同时更新共享内存中的跳过列表的算法 [Pug89a]。这种算法比并发平衡树算法简单得多。它们在 n 个元素的跳过列表中允许无限数量的读取器和 n 个忙碌的写入器,并且锁争用非常少。

这引出了另一篇名为Concurrent Maintenance of Skip Lists 的文章,该文章专门研究了一个由多个读者和作者共同完成的结构。这涉及到编写器需要等待锁定多长时间以及整个结构的加速速度有多快。

因此,由于这些属性,它允许结构中的多个读取器和写入器以最少的锁定和结构平衡。

至于为什么Java库中没有非并发跳转列表?这意味着将代码复制到另一个包(这很糟糕)并且不会真正获得任何东西。没有什么说你不能在不受并发问题限制的地方使用并发包。问题是他们需要两种类型的 Map 来进行并发工作,一个 O(1) HashMap 和一个 O(log n) 树。由于 TreeMap 无法实现良好的并发实现,因此他们决定将其更改为 SkipList。

相关阅读:

【讨论】:

  • @MichaelT 我的图片是错误的,因为我的箭头是相交的???当我看到维基上的图片时 - 我很困惑。
  • @gstackoverflow 跳过列表的每个元素都有 1 个或多个“级别”。每个级别都连接到具有至少相同级别数的下一个元素。在我的图片中,元素 1 有 4 层 - 底层连接到元素 2,第二层连接到元素 3(因为元素 2 只有一层),层 3 连接到元素 4(因为元素 3 只有 2 层高) 和 4 级连接到终结器(因为没有其他元素是 4 级高)。每个级别都是它自己的链表。
  • @MichaelT T有什么更好的用途 - 用于非并发程序的 ConcurrentSkipListSet 或 TreeSet?
  • @gstackoverflow 您没有显示级别。如果元素 1 有一个指向 4 的指针,而元素 3 有一个指向 5 的指针,这意味着 3 也应该有一个指向 4 的指针。这不是关于一组列表,每个列表都在底部 mod n 上。至于哪个更适合非并发编程?它要么没关系(你没有传递TreeMapConcurrentSkipListMap,你应该传递NavigableMap 或只是传递Map 是必要的。如果你认为你真的确实对 TreeMap 与 SkipList 有性能问题,对其进行分析并找出答案。
  • 如果元素 1 有一个指向 4 的指针,而元素 3 有一个指向 5 的指针,这意味着 3 也应该有一个指向 4 的指针。 == 箭头应该'不相交 或 != ?
【解决方案2】:
  1. 任何数据结构都独立于并发性。请参阅 collections 包中的 Java List 实现。 LinkedList 不是线程安全的,但您可以使用 Collections 类来实现。
  2. 为 SkipList 编写实现的个人决定在类中构建线程安全性。那是一个实施决策。

【讨论】:

  • 如何有效地使用 ConcurrentSkipListSet 作为 lib 客户端?
  • 我无法回答任何要求。
猜你喜欢
  • 1970-01-01
  • 2012-09-22
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 2017-11-24
  • 2013-11-14
  • 2023-03-13
相关资源
最近更新 更多