使用传统HashTable保证线程问题,是采用synchronized锁将整个HashTable中的数组锁住, 在多个线程中只允许一个线程访问Put或者Get,效率非常低,但是能够保证线程安全问题。
Jdk官方不推荐在多线程的情况下使用HashTable或者HashMap,建议使用ConcurrentHashMap分段HashMap。 效率非常高。
ConcurrentHashMap将一个大的HashMap集合拆分成n多个不同的小的HashTable(Segment),默认的情况下是分成16个不同的 Segment。每个Segment中都有自己独立的HashEntry<K,V>[] table;
一直卡死,消耗cpu资源,一直重试。
底层使用synchronized锁实现的,但是将整个数组都给锁住了。
将一个大的ConcurrentHashMap集合拆分成n多个不同的hashtable,在每个小的hashtable中都有自己的table【】
package com.gtf.xc;
import java.util.HashMap;
public class MyConcurrentHashMap
<K, V> {
/**
* segments
*/
private HashMap<K,V>[] segments;
public MyConcurrentHashMap() {
segments=new HashMap[16];
//注意是懒加载
}
public void put(K key, V value) {
//第一次计算key,计算key存放在哪一个hashtable
int segmentsIndex =key.hashCode()& (segments.length - 1);
HashMap<K, V> segment = segments[segmentsIndex];
//segment == null
if (segment == null) {
segment=new HashMap<>();
}
segment.put(key,value);
segments[segmentsIndex]=segment;
}
public V get(K key) {
int segmentsIndex =key.hashCode()& (segments.length - 1);
HashMap<K, V> segment = segments[segmentsIndex];
if (segment != null) {
return segment.get(key);
}
return null;
}
public static void main(String[] args) {
MyConcurrentHashMap<Object, Object> objectObjectMyConcurrentHashMap = new MyConcurrentHashMap<>();
for (int i = 0; i < 10; i++){
objectObjectMyConcurrentHashMap.put(i,i);
}
for (int i = 0; i < 10; i++) {
objectObjectMyConcurrentHashMap.get(i);
System.out.println( objectObjectMyConcurrentHashMap.get(i));
}
}
}
ConcurrentHashMap1.8的取出取消segment分段设计,采用对CAS + synchronized保证并发线程安全问题,将锁的粒度拆分到每个index 下标位置,实现的效率与ConcurrentHashMap1.7相同。