ConcurrentSkipListSet内部工作原理,与TreeSet的区别。

huangapple go评论76阅读模式
英文:

ConcurrentSkipListSet internal working, difference from TreeSet

问题

只有我理解的区别在于迭代器之间。SkipList 使用弱一致性,而 TreeSet 使用快速失败机制。除此之外,我在 SkipList 内部没有看到任何同步方法(尽管它在并发包中)。

有人能解释一下,既然 SkipList 内部没有任何同步机制,它是如何实现并发的呢?除了迭代器方面的区别,它能解决什么问题?为什么我要使用它?

英文:

Only difference I understand is between iterators. SkipList has weakly consistent, while TreeSet has fail-fast. Other than that I don't see any synchronized methods inside SkipList (although it is in Concurrent package).

Can someone please explain to me how is SkipList concurrent when it doesn't have any synchronization in it? What problems can it help me with and why should I ever use it other than this difference between Iterators?

答案1

得分: 4

> „…SkipList在没有任何同步的情况下如何实现并发?…

简而言之ConcurrentSkipListSet并发的,因为它所持有的元素不能同时被并发执行的线程写入。它在不使用 synchronized 和锁的情况下实现了并发


详细说明

在并发集合的上下文中,并发 并不一定意味着这些类都使用监视器(也就是 synchronized 关键字)来实现线程安全。

首先,你应该明白线程安全实质上是确保两个或更多竞争线程不会修改应用程序的共享状态。然后你会意识到,除了 synchronized 之外,还有其他方式(一些性能更高的方式)可以实现线程安全。

确保状态不可被修改(即状态是不可变的)是实现线程安全的一种简单但非常有效的方法。

另外,一个类可以通过将其线程安全的责任委托给不同的线程安全类来实现线程安全。

ConcurrentSkipListSet 被认为是 并发的,因为根据其 Javadoc 描述,它的:“插入、删除、更新和访问操作可以由多个线程安全地并发执行”。

它之所以实现了并发,是因为它将其线程安全责任委托给了一个线程安全的类,即:ConcurrentSkipListMap

ConcurrentSkipListSet 是线程安全的,因为 ConcurrentSkipListMap 也是线程安全的。而 ConcurrentSkipListMap 之所以是线程安全的,是因为它在内部使用 AbstractMap.SimpleImmutableEntry<K,V>,从而保证了其状态(即键和值)不会被当前执行的线程修改,因为它的状态是不可变的

你可以在我上面链接的源代码中的多个地方看到 ConcurrentSkipListSet 委托给 ConcurrentSkipListMap。如果你对委托线程安全有更多兴趣,我推荐你阅读第四章,组合对象,Java并发实战

> „…它可以帮我解决哪些问题?

使用它可以获得免费的线程安全。这种线程安全方式比使用 synchronized 更加高效,而且风险更小。

> „…除了迭代器的差异,我为什么要使用它?

如果你的应用程序的状态需要存储在某个集合中,并且该集合将以任何方式被并发执行的线程访问,那么使用 ConcurrentSkipListSet 是一个线程安全的选择。

英文:

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

TL;DRConcurrentSkipListSet is concurrent because the elements it holds cannot be written to at the same time by concurrently executing threads. It achieves its concurrency without using synchronized and locks.


The long version

Concurrency in the context of the concurrent collections, does not necessarily mean those classes all implement thread safety using monitors (aka, the synchronized keyword).

First you should understand that thread safety is essentially about ensuring that two or more competing threads do not modify the shared state of an application. Then you realize that there are ways (some more performant) other than synchronized to achieve thread safety.

Making sure your state cannot be modified (that it's immutable) in the first place is one simple but very effective way to get thread safety.

Also, a class can be thread safe by delegating its thread safety responsibilities to a different, thread-safe class.

ConcurrentSkipListSet is considered to be concurrent because, as its Javadoc says, its: „Insertion, removal, update, and access operations safely execute concurrently by multiple threads“.

It achieves its concurrency because it delegates its thread safety responsibilities to a thread-safe class; namely: ConcurrentSkipListMap.

ConcurrentSkipListSet is thread-safe because ConcurrentSkipListMap is. And ConcurrentSkipListMap is thread-safe because, by using AbstractMap.SimpleImmutableEntry<K,V> internally, it guarantees that none of its state (its keys and values) can be modified by currently executing threads, because its state is immutable.

You can see ConcurrentSkipListSet delegating to ConcurrentSkipListMap at several places in the source code I linked to above. If you're interested in learning more about delegating thread safety, I recommend you read Chapter 4, Composing Objects, Java Concurrency In Practice.

> „…What problems can it help me with

Using it gets you free thread-safety. The kind that is way more performant — and with way less risk of shooting yourself in the foot — than using synchronized.

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

If the state of your application needs to be stored in some collection and that collection will be accessible in any way to concurrently executing threads, then using ConcurrentSkipListSet is a thread-safe option that you have.

huangapple
  • 本文由 发表于 2020年8月23日 05:31:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/63541301.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定