ConcurrentMap接口继承自Map接口,并定义了最实用的并发集合类型之一。在原有的Map接口基础上又新提供了4种方法:
- getOrDefault()返回指定键的值。在传入的键不存在时,返回默认值
- putIfAbsent()如果插入的key相同,怎么不替换原有的value
- remove(K,V)如果要删除的key-value不能对应,则不会删除
- replace(K,V,V)如果key-oldValue与原有键值对应,才进行替换操作
package com.test.collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class ConcurrentHashMapTest {
public static void main(String[] args) {
ConcurrentMap<String, Object> map = new ConcurrentHashMap<String, Object>();
map.put("home", "hangzhou");
//新增方法 getOrDefault 获取一个key对应的值 如果key不存在就返回默认值
// System.out.println(map.getOrDefault("home1", "zhejiang"));
// putIfAbsent 如果原来已经有key存在则不替换
map.putIfAbsent("home", "shanghai");
// System.out.println(map.get("home"));
// 删除指定的key 只有当value相同时 才会删除
map.remove("home", "hangzhou");
System.out.println(map.get("home"));
}
}
主要的实现类ConcurrentHashMap。ConcurrentHashMap使用锁分段技术解决HashTable在线程并发时效率低下的问题。首先将数据分成一段一段存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个数据段时,其他段的数据也能被其他线程访问。有些方法需要跨段,例如size和containsValue,他们可能需要锁定整个表而不仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。
ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap中扮演锁的角色,HashEntry则用于存储键值对。一个ConcurrentHashMap里包含一个segment数组,Segment的结构和HashMap相似,是一种数组和链表结构,一个Segment中包含一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。