map collection which is thread-safe

Why HashMap is not thread safe

Always said HashMap is not thread-safe, unsafe, insecure, then in the end why it is thread safe it? To answer this question we must first take a brief look at the source code used HashMap 存储结构(Java source code is incorporated herein by reference 8, and 7 is not the same) and it is 扩容机制.

HashMap internal storage array using a Node (default size is 16), and comprises a Node type for the next class of Node variable, which is equivalent to a list, all in accordance with the same hash value calculated will be stored in the same bucket key a linked list (ie, had a conflict).

img

HashMap of automatic expansion mechanism

Node HashMap internal array 16 is the default size, assumed that there are one million elements, each hash bucket element 62500 has the best case, then get (), put (), remove () method and the like efficiency will be reduced. To solve this problem, HashMap provides a mechanism for automatic expansion, when the number of elements in the array size is reached loadFactor will expand the size of the array, by default, the array size is 16, loadFactor 0.75, that is when the elements exceed HashMap 16 \ 0.75 = 12, the size of the array will be extended to 2 * 16 = 32, and recalculating the position of each element in the new array.

Why not thread safe

HashMap personally think the problem may occur when concurrent mainly two aspects, first of all, if multiple threads simultaneously put method to add elements, but there are two assumptions just put the key in a collision (the same hash value is calculated according to the bucket), then Depending on the implementation HashMap, the two key is added to the same location in the array, so that eventually occurs in one of the threads put data is overwritten. If a second plurality of threads is detected number of elements in the array exceeds the size * loadFactor, a plurality of threads simultaneously on the Node array such expansion occurs, the element positions are recalculated and copying data, but ultimately only one thread expansion the array will be assigned to the table, that is to say will be lost to other threads, and each thread put data is also lost.

"Java concurrent programming Art," a book had this to say: HashMap concurrent execution put in operation may cause an infinite loop, resulting in close to 100% CPU utilization. Because multiple threads can lead to the formation of a ring of HashMap Node list data structure, data structure to form a ring once, the next node Node never empty, it will generate an infinite loop in acquiring Node.

Infinite loop does not occur when put in operation, but in the time of expansion.

How to use HashMap thread-safe

Learn why HashMap thread-safe, now look at how to use thread-safe HashMap. This is nothing more than the following three ways:

  • Hashtable

    HashTable的get/put方法都被synchronized关键字修饰,说明它们是方法级别阻塞的,它们占用共享资源锁,所以导致同时只能一个线程操作get或者put,而且get/put操作不能同时执行,所以这种同步的集合效率非常低,一般不建议使用这个集合。
  • ConcurrentHashMap

    private Map<String, Object> map = new ConcurrentHashMap<>();
    这个也是最推荐使用的线程安全的Map,也是实现方式最复杂的一个集合,每个版本的实现方式也不一样,在jdk8之前是使用分段加锁的一个方式,分成16个桶,每次只加锁其中一个桶,而在jdk8又加入了红黑树和CAS算法来实现。
  • Synchronized Map

    private Map<String, Object> map = Collections.synchronizedMap(new HashMap<String, Object>());
    这种是直接使用工具类里面的方法创建SynchronizedMap

https://www.cnblogs.com/yaowen/p/9634368.html

https://www.cnblogs.com/xwjBlog/p/9708198.html

Guess you like

Origin www.cnblogs.com/PoetryAndYou/p/11615705.html