最近在探索ConcurrentSkipListMap
时,我经历了它的实现,发现它的put方法不是线程安全的。它在内部调用实际添加项目的doPut
。但我发现这种方法不使用任何类似于ConcurrentHashMap
的锁。
因此,我想知道add
是否是线程安全的。看看这个方法似乎不是线程安全的 - 也就是说,如果这个方法同时由两个线程执行,那么可能会出现问题。
我知道ConcurrentSkipListMap
内部使用了跳过列表数据结构,但我希望add
方法是线程安全的。我理解有什么不对吗? ConcurrentSkipListMap
真的不是线程安全的吗?
答案 0 :(得分:2)
仅仅因为它不使用Lock
并不会使其线程不安全。 Skip list结构可以实现lock free。
您应该仔细阅读API。
...插入,删除,更新和访问操作由多个线程安全地并行执行。迭代器是弱一致的,在迭代器创建时或之后的某个时刻返回反映地图状态的元素。它们不会抛出ConcurrentModificationException,并且可以与其他操作同时进行。 ...
答案 1 :(得分:1)
我们应该信任Java API。这就是java.util.concurrent包文档所说的:
并发收藏
除了Queues之外,这个包还提供了设计用于多线程上下文的Collection实现:ConcurrentHashMap,ConcurrentSkipListMap
,ConcurrentSkipListSet,CopyOnWriteArrayList和CopyOnWriteArraySet。
答案 2 :(得分:1)
执行中的评论说:
考虑到使用树状索引节点,您可能想知道为什么会这样 不会使用某种搜索树,而是支持 搜索操作有点快。原因是没有 用于搜索的已知有效的无锁插入和删除算法 树木。 " down"的不变性。索引节点的链接(相反 可变的"左"真树中的字段)使这个易于使用 只有CAS操作。
因此,他们使用比较和交换操作的一些低级编程功能来对地图原子进行更改。通过这种方式,他们可以确保线程安全,而无需同步访问。
您可以在源代码中更详细地阅读它。