2

假设我有一个包含很多字段的数据结构。我想使用线程以并发方式访问它。无论如何,我不想锁定整个结构(例如,使用大互斥锁对其进行完全独占访问),但我希望一个线程可以访问一个字段,即使其他线程正在访问其他字段。可能吗?如果是,如何?

4

3 回答 3

1

Java 有ConcurrentSkipListMap和 ConcurrenSkipListSet 非常非常适合这种情况。它还有一个 ConcurrentHashMap,它在多线程环境中不是那么快,但它是线程安全的。我认为大多数语言都可以使用类似的东西。跳过列表的想法(一个像字典/映射并使用比较和交换而不是锁定的单链表)是相当新的,但是自己锁定的哈希表已经存在了很久。(如果你不使用 Java 并且找不到东西,Java 是开源的,所以你可以翻译代码并自己制作。)

于 2012-06-14T20:32:13.107 回答
0

那么直接的方法是有一个单独的互斥锁来保护每个字段,假设您可以承受内存开销。

编辑:由于您在谈论哈希表,因此锁定每个插槽会产生过多的开销,而单个锁的效率会太低。

最可接受的方式是锁分条技术,这意味着维护 K 个锁,每个保护M/K槽(M 是槽的总数)。然后,您可以运行一些基准测试并调整 K 以获得最佳性能。

于 2012-06-14T14:52:30.040 回答
0

您可以只为整个哈希表使用一个锁,而不是拥有一大堆锁,但为表中的每个元素使用一个标志。Flag 表示该元素当前已被其他人使用,想要使用它的人必须稍等片刻。因此,要从表中获取元素,您需要通过单个锁,但一旦获取元素,您就会释放它。之后,您检查是否允许使用该元素。如果没有,请稍等并再次检查。

如果可以从哈希表中删除元素,则必须为每个元素设置一个引用计数,以便只有在引用计数降至零时才能删除元素并将其从表中删除。

当新元素被添加到表中时,它是在表的锁内完成的。锁也用于删除元素。希望访问现有元素比创建新元素和删除现有元素更频繁。

于 2012-06-14T15:16:36.690 回答