简体   繁体   English

ConcurrentHashMap 内部是如何工作的?

[英]How does ConcurrentHashMap work internally?

I was reading the official Oracle documentation about Concurrency in Java and I was wondering what could be the difference between a Collection returned by我正在阅读有关 Java 并发的 Oracle 官方文档,我想知道返回的Collection之间有什么区别

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

and using for example a并使用例如

ConcurrentHashMap . ConcurrentHashMap I'm assuming that I use synchronizedCollection(Collection<T> c) on a HashMap .我假设我在HashMap上使用synchronizedCollection(Collection<T> c) I know that in general a synchronized collection is essentially just a decorator for my HashMap so it is obvious that a ConcurrentHashMap has something different in its internals.我知道一般来说,同步集合本质上只是我的HashMap的装饰器,因此很明显ConcurrentHashMap的内部结构有所不同。 Do you have some information about those implementation details?你有关于这些实现细节的一些信息吗?

Edit: I realized that the source code is publicly available: ConcurrentHashMap.java编辑:我意识到源代码是公开可用的: ConcurrentHashMap.java

I would read the source of ConcurrentHashMap as it is rather complicated in the detail.我会阅读ConcurrentHashMap来源,因为它的细节相当复杂。 In short it has总之它有

  • Multiple partitions which can be locked independently.可以独立锁定的多个分区。 (16 by default) (默认为 16)
  • Using concurrent Locks operations for thread safety instead of synchronized.使用并发锁操作来保证线程安全而不是同步。
  • Has thread safe Iterators.具有线程安全迭代器。 synchronizedCollection's iterators are not thread safe. synchronizedCollection 的迭代器不是线程安全的。
  • Does not expose the internal locks.不暴露内部锁。 synchronizedCollection does. synchronizedCollection 确实如此。

The ConcurrentHashMap is very similar to the java.util.HashTable class, except that ConcurrentHashMap offers better concurrency than HashTable or synchronizedMap does. ConcurrentHashMapjava.util.HashTable类非常相似,除了ConcurrentHashMap提供比HashTablesynchronizedMap更好的并发性。 ConcurrentHashMap does not lock the Map while you are reading from it. ConcurrentHashMap在您读取 Map 时不会锁定它。 Additionally, ConcurrentHashMap does not lock the entire Map when writing to it.此外, ConcurrentHashMap在写入时不会锁定整个Map It only locks the part of the Map that is being written to, internally.它只在内部锁定正在写入的Map部分。

Another difference is that ConcurrentHashMap does not throw ConcurrentModificationException if the ConcurrentHashMap is changed while being iterated.另一个区别是,如果ConcurrentHashMap在迭代时发生更改,则 ConcurrentHashMap 不会抛出ConcurrentModificationException The Iterator is not designed to be used by more than one thread though whereas synchronizedMap may throw ConcurrentModificationException Iterator并非设计为由多个线程使用,而synchronizedMap可能会抛出ConcurrentModificationException

This is the article that helped me understand it Why ConcurrentHashMap is better than Hashtable and just as good as a HashMap这篇文章帮助我理解了为什么 ConcurrentHashMap 比 Hashtable 更好并且和 HashMap 一样好

Hashtable's offer concurrent access to their entries, with a small caveat, the entire map is locked to perform any sort of operation. Hashtable 提供对其条目的并发访问,但需要注意的是,整个映射被锁定以执行任何类型的操作。 While this overhead is ignorable in a web application under normal load, under heavy load it can lead to delayed response times and overtaxing of your server for no good reason.虽然这种开销在正常负载下的 web 应用程序中是可以忽略的,但在重负载下,它可能会导致响应时间延迟和服务器无缘无故地负担过重。

This is where ConcurrentHashMap's step in. They offer all the features of Hashtable with a performance almost as good as a HashMap.这就是 ConcurrentHashMap 的用武之地。它们提供了 Hashtable 的所有功能,并且性能几乎与 HashMap 一样好。 ConcurrentHashMap's accomplish this by a very simple mechanism. ConcurrentHashMap 通过一个非常简单的机制来实现这一点。 Instead of a map wide lock, the collection maintains a list of 16 locks by default, each of which is used to guard (or lock on) a single bucket of the map.该集合默认维护一个包含 16 个锁的列表,而不是地图范围的锁,每个锁用于保护(或锁定)地图的单个存储桶。 This effectively means that 16 threads can modify the collection at a single time (as long as they're all working on different buckets).这实际上意味着 16 个线程可以一次修改集合(只要它们都在不同的存储桶上工作)。 Infact there is no operation performed by this collection that locks the entire map.事实上,这个集合没有执行锁定整个地图的操作。 The concurrency level of the collection, the number of threads that can modify it at the same time without blocking, can be increased.集合的并发级别,可以在不阻塞的情况下同时修改它的线程数,可以增加。 However a higher number means more overhead of maintaining this list of locks.然而,更高的数字意味着维护这个锁列表的开销更大。

The "scalability issues" for Hashtable are present in exactly the same way in Collections.synchronizedMap(Map) - they use very simple synchronization, which means that only one thread can access the map at the same time. Hashtable的“可扩展性问题”在Collections.synchronizedMap(Map)以完全相同的方式存在——它们使用非常简单的同步,这意味着只有一个线程可以同时访问映射。

This is not much of an issue when you have simple inserts and lookups (unless you do it extremely intensively), but becomes a big problem when you need to iterate over the entire Map, which can take a long time for a large Map - while one thread does that, all others have to wait if they want to insert or lookup anything.当您进行简单的插入和查找时,这不是什么大问题(除非您非常密集地执行此操作),但是当您需要遍历整个 Map 时会成为一个大问题,这对于大型 Map 可能需要很长时间 - 而一个线程这样做,所有其他线程如果要插入或查找任何内容都必须等待。

The ConcurrentHashMap uses very sophisticated techniques to reduce the need for synchronization and allow parallel read access by multiple threads without synchronization and, more importantly, provides an Iterator that requires no synchronization and even allows the Map to be modified during interation (though it makes no guarantees whether or not elements that were inserted during iteration will be returned). ConcurrentHashMap使用非常复杂的技术来减少同步的需要,并允许多个线程在没有同步的情况下并行读取访问,更重要的是,它提供了一个不需要同步的迭代器,甚至允许在交互期间修改 Map(尽管它不保证是否会返回在迭代期间插入的元素)。

Returned by synchronizedCollection() is an object all methods of which are synchronized on this , so all concurrent operations on such wrapper are serialized. synchronizedCollection()返回的是一个对象,其所有方法都在this上同步,因此此类包装器上的所有并发操作都被序列化。 ConcurrentHashMap is a truly concurrent container with fine grained locking optimized to keep contention as low as possible. ConcurrentHashMap 是一个真正的并发容器,具有优化的细粒度锁定以保持尽可能低的争用。 Have a look at the source code and you will see what it is inside.看看源代码,你会看到它里面的内容。

ConcurrentHashMap implements ConcurrentMap which provides the concurrency. ConcurrentHashMap 实现了提供并发性的 ConcurrentMap。 Deep internally its iterators are designed to be used by only one thread at a time which maintains the synchronization.在内部,它的迭代器被设计为一次仅由一个线程使用,以保持同步。 This map is used widely in concurrency.此映射在并发中被广泛使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM