[英]When should I use ConcurrentSkipListMap?
In Java, ConcurrentHashMap
is there for better multithreading
solution.在 Java 中,
ConcurrentHashMap
用于更好的multithreading
解决方案。 Then when should I use ConcurrentSkipListMap
?那我什么时候应该使用
ConcurrentSkipListMap
? Is it a redundancy?是裁员吗?
Does multithreading aspects between these two are common?这两者之间的多线程方面是否常见?
These two classes vary in a few ways.这两个类在几个方面有所不同。
ConcurrentHashMap does not guarantee* the runtime of its operations as part of its contract. ConcurrentHashMap不保证*其操作的运行时间作为其合同的一部分。 It also allows tuning for certain load factors (roughly, the number of threads concurrently modifying it).
它还允许调整某些负载因子(粗略地说,同时修改它的线程数)。
ConcurrentSkipListMap , on the other hand, guarantees average O(log(n)) performance on a wide variety of operations.另一方面, ConcurrentSkipListMap保证了各种操作的平均 O(log(n)) 性能。 It also does not support tuning for concurrency's sake.
它也不支持为了并发而进行调优。
ConcurrentSkipListMap
also has a number of operations that ConcurrentHashMap
doesn't: ceilingEntry/Key, floorEntry/Key, etc. It also maintains a sort order, which would otherwise have to be calculated (at notable expense) if you were using a ConcurrentHashMap
. ConcurrentSkipListMap
也有许多ConcurrentHashMap
没有的操作:ceilingEntry/Key、floorEntry/Key 等。它还维护一个排序顺序,否则如果您使用ConcurrentHashMap
则必须计算(费用显着)。
Basically, different implementations are provided for different use cases.基本上,为不同的用例提供了不同的实现。 If you need quick single key/value pair addition and quick single key lookup, use the
HashMap
.如果您需要快速添加单键/值对和快速单键查找,请使用
HashMap
。 If you need faster in-order traversal, and can afford the extra cost for insertion, use the SkipListMap
.如果您需要更快的有序遍历,并且可以承受插入的额外成本,请使用
SkipListMap
。
*Though I expect the implementation is roughly in line with the general hash-map guarantees of O(1) insertion/lookup; *虽然我希望实现大致符合 O(1) 插入/查找的一般哈希映射保证; ignoring re-hashing
忽略重新散列
See Skip List for a definition of the data structure.有关数据结构的定义,请参阅跳过列表。
A ConcurrentSkipListMap
stores the Map
in the natural order of its keys (or some other key order you define). ConcurrentSkipListMap
以其键的自然顺序(或您定义的其他键顺序)存储Map
。 So it'll have slower get
/ put
/ contains
operations than a HashMap
, but to offset this it supports the SortedMap
, NavigableMap
, and ConcurrentNavigableMap
interfaces.所以它的
get
/ put
/ contains
操作比HashMap
慢,但为了抵消这一点,它支持SortedMap
、 NavigableMap
和ConcurrentNavigableMap
接口。
In terms of performance, skipList
when is used as Map - appears to be 10-20 times slower.在性能方面,当用作 Map 时,
skipList
会慢 10-20 倍。 Here is the result of my tests (Java 1.8.0_102-b14, win x32)这是我的测试结果(Java 1.8.0_102-b14,win x32)
Benchmark Mode Cnt Score Error Units
MyBenchmark.hasMap_get avgt 5 0.015 ? 0.001 s/op
MyBenchmark.hashMap_put avgt 5 0.029 ? 0.004 s/op
MyBenchmark.skipListMap_get avgt 5 0.312 ? 0.014 s/op
MyBenchmark.skipList_put avgt 5 0.351 ? 0.007 s/op
And additionally to that - use-case where comparing one-to-another really makes sense.除此之外 - 一对一比较真正有意义的用例。 Implementation of the cache of last-recently-used items using both of these collections.
使用这两个集合实现上次最近使用的项目的缓存。 Now efficiency of skipList looks to be event more dubious.
现在skipList 的效率看起来更令人怀疑。
MyBenchmark.hashMap_put1000_lru avgt 5 0.032 ? 0.001 s/op
MyBenchmark.skipListMap_put1000_lru avgt 5 3.332 ? 0.124 s/op
Here is the code for JMH (executed as java -jar target/benchmarks.jar -bm avgt -f 1 -wi 5 -i 5 -t 1
)这是 JMH 的代码(执行为
java -jar target/benchmarks.jar -bm avgt -f 1 -wi 5 -i 5 -t 1
)
static final int nCycles = 50000;
static final int nRep = 10;
static final int dataSize = nCycles / 4;
static final List<String> data = new ArrayList<>(nCycles);
static final Map<String,String> hmap4get = new ConcurrentHashMap<>(3000, 0.5f, 10);
static final Map<String,String> smap4get = new ConcurrentSkipListMap<>();
static {
// prepare data
List<String> values = new ArrayList<>(dataSize);
for( int i = 0; i < dataSize; i++ ) {
values.add(UUID.randomUUID().toString());
}
// rehash data for all cycles
for( int i = 0; i < nCycles; i++ ) {
data.add(values.get((int)(Math.random() * dataSize)));
}
// rehash data for all cycles
for( int i = 0; i < dataSize; i++ ) {
String value = data.get((int)(Math.random() * dataSize));
hmap4get.put(value, value);
smap4get.put(value, value);
}
}
@Benchmark
public void skipList_put() {
for( int n = 0; n < nRep; n++ ) {
Map<String,String> map = new ConcurrentSkipListMap<>();
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
map.put(key, key);
}
}
}
@Benchmark
public void skipListMap_get() {
for( int n = 0; n < nRep; n++ ) {
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
smap4get.get(key);
}
}
}
@Benchmark
public void hashMap_put() {
for( int n = 0; n < nRep; n++ ) {
Map<String,String> map = new ConcurrentHashMap<>(3000, 0.5f, 10);
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
map.put(key, key);
}
}
}
@Benchmark
public void hasMap_get() {
for( int n = 0; n < nRep; n++ ) {
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
hmap4get.get(key);
}
}
}
@Benchmark
public void skipListMap_put1000_lru() {
int sizeLimit = 1000;
for( int n = 0; n < nRep; n++ ) {
ConcurrentSkipListMap<String,String> map = new ConcurrentSkipListMap<>();
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
String oldValue = map.put(key, key);
if( (oldValue == null) && map.size() > sizeLimit ) {
// not real lru, but i care only about performance here
map.remove(map.firstKey());
}
}
}
}
@Benchmark
public void hashMap_put1000_lru() {
int sizeLimit = 1000;
Queue<String> lru = new ArrayBlockingQueue<>(sizeLimit + 50);
for( int n = 0; n < nRep; n++ ) {
Map<String,String> map = new ConcurrentHashMap<>(3000, 0.5f, 10);
lru.clear();
for( int i = 0; i < nCycles; i++ ) {
String key = data.get(i);
String oldValue = map.put(key, key);
if( (oldValue == null) && lru.size() > sizeLimit ) {
map.remove(lru.poll());
lru.add(key);
}
}
}
}
Then when should I use ConcurrentSkipListMap?
那么我应该什么时候使用 ConcurrentSkipListMap 呢?
When you (a) need to keep keys sorted, and/or (b) need the first/last, head/tail, and submap features of a navigable map.当您 (a) 需要对键进行排序,和/或 (b) 需要可导航地图的第一个/最后一个、头/尾和子地图功能时。
The ConcurrentHashMap
class implements the ConcurrentMap
interface, as does ConcurrentSkipListMap
. ConcurrentHashMap
类实现了ConcurrentMap
接口, ConcurrentSkipListMap
也是如此。 But if you also want the behaviors of SortedMap
and NavigableMap
, use ConcurrentSkipListMap
但如果您还想要
SortedMap
和NavigableMap
的行为,请使用ConcurrentSkipListMap
ConcurrentHashMap
ConcurrentSkipListMap
Here is table guiding you through the major features of the various Map
implementations bundled with Java 11. Click/tap to zoom.下表指导您了解与 Java 11 捆绑在一起的各种
Map
实现的主要功能。单击/点击以进行缩放。
Keep in mind that you can obtain other Map
implementations, and similar such data structures, from other sources such as Google Guava .请记住,您可以从其他来源(例如Google Guava )获取其他
Map
实现和类似的此类数据结构。
基于工作负载,如果需要范围查询,ConcurrentSkipListMap 可能比KAFKA-8802 中使用同步方法的 TreeMap 慢。
ConcurrentHashMap : when u want multithreaded index based get/put, only index based operations are supported. ConcurrentHashMap :当你想要基于多线程索引的 get/put 时,只支持基于索引的操作。 Get/Put are of O(1)
Get/Put 是 O(1)
ConcurrentSkipListMap : More operations than just get/put, like sorted top/bottom n items by key, get last entry, fetch/traverse whole map sorted by key etc. Complexity is of O(log(n)), So put performance is not as great as ConcurrentHashMap. ConcurrentSkipListMap :不仅仅是获取/放置更多的操作,比如按键排序顶部/底部 n 项,获取最后一个条目,获取/遍历按键排序的整个地图等。复杂性是 O(log(n)),所以 put 性能不是和 ConcurrentHashMap 一样伟大。 It't an implementation of ConcurrentNavigableMap with SkipList.
它不是 ConcurrentNavigableMap 与 SkipList 的实现。
To summarize use ConcurrentSkipListMap when you want to do more operations on map requiring sorted features rather than just simple get and put.总而言之,当您想要对需要排序功能的地图进行更多操作而不是简单的获取和放置时,请使用 ConcurrentSkipListMap。
It is providing expected average log(n) time cost for the contains Key, get, put and remove operations and their variants.它为包含 Key、get、put 和 remove 操作及其变体提供预期的平均 log(n) 时间成本。 Insertion, removal, update, and access operations safely execute concurrently by multiple threads.
插入、删除、更新和访问操作由多个线程安全地并发执行。 Best if you want to use in multithreading
如果你想在多线程中使用最好
for more details check here https://medium.com/@deepika451408/concurrentskiplistmap-779ec3b7f28d有关详细信息,请在此处查看https://medium.com/@deepika451408/concurrentskiplistmap-779ec3b7f28d
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.