非线程安全的HashMap怎么着在二十多线程中动用

Java 非线程安全的HashMap怎么着在八线程中应用

 

HashMap 是非线程安全的。在三四线程条件下,轻松导致死循环,具体表现为CPU使用率百分之百。由此多线程意况下有限援助HashMap 的线程安全性,首要有如下两种方法:

  1. 选拔 java.util.Hashtable 类,此类是线程安全的。
  2. 动用 java.util.concurrent.ConcurrentHashMap,此类是线程安全的。
  3. 应用 java.util.Collections.synchronizedMap() 方法包装 HashMap object,获得线程安全的Map,并在此Map上进行操作。
  4. 友善在程序的第一代码段加锁,保证十二线程安全(不引入)

 

接下去分析上边列举的两种艺术完成产出安全的 HashMap 的法规:

(一)java.util.Hashtable类:

查看该类的源码

public synchronized V get(Object key) {  
    …… //具体的实现省略,请参考 jdk实现  
}  

public synchronized V put(K key, V value) {  
    …… //具体的实现省略,请参考 jdk实现  
}  

public synchronized V remove(Object key) {  
    …… //具体的实现省略,请参考 jdk实现  
}  

     下面是 Hashtable 类提供的多少个主要措施,包含 get(),put(),remove() 等。注意到各种方法自己都是 synchronized 的,不会并发多个线程同期对数据开展操作的气象,因而保险了线程安全性,然则也大大的裁减了推行作用。因此是不推荐的。

 

(二)使用 java.util.concurrent.ConcurrentHashMap 类:

该类是 HashMap 的线程安全版,与 Hashtable 相比较, ConcurrentHashMap 不独有有限帮衬了拜会的线程安全性,何况在功效上有十分的大的抓好。

ConcurrentHashMap的数据结构如下:

图片 1

能够见到,绝对 HashMap 和 Hashtable, ConcurrentHashMap 增添了Segment 层,每一种Segment 原理上一样五个 Hashtable, ConcurrentHashMap 等同于三个 Segment 的数组。下边是 ConcurrentHashMap 的 put 和 get 方法:

final Segment<K,V> segmentFor(int hash) {  
    return segments[(hash >>> segmentShift) & segmentMask];  
}  

public V put(K key, V value) {  
    if (value == null)  
        throw new NullPointerException();  
    int hash = hash(key.hashCode());  
    return segmentFor(hash).put(key, hash, value, false);  
}  

public V get(Object key) {  
    int hash = hash(key.hashCode());  
    return segmentFor(hash).get(key, hash);  
}  

向 ConcurrentHashMap 中插入数据(put) 恐怕读取多少(get),首先都要将相应的 Key 映射到相应的 Segment,进而不要锁定任何类, 只要对单个的 Segment 操作实行上锁操作就可以了。理论上一旦有 n 个 Segment,那么最多能够同时援救 n 个线程的产出访谈,进而大大升高了出现采访的频率。

 

本文由明仕msyz手机版发布于情感专区-情绪智力,转载请注明出处:非线程安全的HashMap怎么着在二十多线程中动用

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。