ConcurrentSkipListSet 内部工作,与 TreeSet 的区别

ConcurrentSkipListSet internal working, difference from TreeSet

我理解的唯一区别是迭代器之间的区别。 SkipList 具有 弱一致性 ,而 TreeSet 具有 快速失败 。除此之外,我在 SkipList 中看不到任何同步方法(尽管它在 Concurrent 包中)。

有人可以向我解释 SkipList 在没有任何同步的情况下如何并发吗?它可以帮助我解决什么问题,除了迭代器之间的区别之外,我为什么要使用它?

…how is SkipList concurrent when it doesn't have any synchronization in it?…

TL;DRConcurrentSkipListSet concurrent因为它持有的元素不能被concurrently[=93=同时写入] 执行线程。它在不使用 synchronized 和锁的情况下实现了 并发性


长版

Concurrency 在并发集合的上下文中,并不一定意味着那些 classes 都使用监视器实现线程安全(aka, synchronized 关键字).

首先,您应该了解线程安全本质上是关于确保两个或多个竞争线程不会修改应用程序的共享状态。然后你意识到除了 synchronized 之外还有其他方法(一些更高效的)来实现线程安全。

首先确保您的状态不能被修改(它是不可变的)是获得线程安全的一种简单但非常有效的方法。

此外,class 可以通过 将其线程安全责任委托给 另一个 thread-safe class.[= 线程安全。 31=]

ConcurrentSkipListSet 被认为是 concurrent 因为,作为它的 Javadoc说,其:“Insertion, removal, update, and access operations safely execute concurrently by multiple threads”。

它实现了 并发性 因为它 delegates its thread safety responsibilities to a thread-safe class;即:ConcurrentSkipListMap.

ConcurrentSkipListSet 是 thread-safe 因为 ConcurrentSkipListMap 是。而 ConcurrentSkipListMap 是 thread-safe 因为,通过在内部使用 AbstractMap.SimpleImmutableEntry<K,V>,它保证了其状态的 none(它的键和值) 可以被当前正在执行的线程修改,因为它的状态是不可变.

你可以在我链接到的源代码的几个地方看到 ConcurrentSkipListSet 委托给 ConcurrentSkipListMap多于。如果您有兴趣了解有关 委托线程安全性 的更多信息,我建议您阅读 Chapter 4, Composing Objects, Java Concurrency In Practice.

…What problems can it help me with

使用它可以获得 免费 thread-safety。那种比使用 synchronized.[= 更高效的方式——而且搬起石头砸自己脚的风险要小—— 31=]

…why should I ever use it other than this difference between Iterators?

如果您的应用程序的状态需要存储在某个集合中并且该集合可以访问任何方式并发执行线程,然后使用 ConcurrentSkipListSet 是您拥有的 thread-safe 选项。