在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文为系列文章第八篇。
由于Java程序员常用的HashMap的操作方法不是同步的,所以在多线程环境下会导致存取操作数据不一致的问题,Map接口的另一个实现类Hashtable 虽然是线程安全的,但是在多线程下执行效率很低。为了解决这个问题,在java 1.5版本中引入了线程安全的集合类ConcurrentMap。
java.util.concurrent.ConcurrentMap
接口是Java集合类框架提供的线程安全的map,这意味着多线程同时访问它,不会影响map中每一条数据的一致性。ConcurrentMap接口有两个实现类ConcurrentHashMap和ConcurrentSkipListMap,经常被使用的是ConcurrentHashMap,我们来重点关注它。
通过下面的代码创建ConcurrentHashMap
// 创建容量为8,负载系数为0.6的ConcurrentHashMap
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
使用上面的代码,我们创建一个叫做numbers的ConcurrentHashMap对象。
需要我们特别注意的是new ConcurrentHashMap<>(8, 0.6)
.
默认容量与负载因子 我们还可以通过下面的代码初始化一个ConcurrentHashMap对象,默认情况下capacity=16,loadFactor=0.75
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
put(K,V)
- 向map中插入key/value 键值对数据putAll(map)
- 把另一个map中的所有entries插入到当前的map中putIfAbsent(K,V)
- 向map中插入key/value 键值对数据,如果该键值对的key在map不存在则插入数据,否则不做操作。import java.util.concurrent.ConcurrentHashMap;
class Main {
public static void main(String[] args) {
// 创建ConcurrentHashMap 用于保存偶数
ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
// 使用put()方法插入数据
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
// 使用putIfAbsent()插入数据
evenNumbers.putIfAbsent("Six", 6);
System.out.println("偶数集合ConcurrentHashMap: " + evenNumbers);
//创建ConcurrentHashMap用于保存整数
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
// 使用putAll()插入数据
numbers.putAll(evenNumbers);
System.out.println("整数集合ConcurrentHashMap: " + numbers);
}
}
输出结果:
偶数集合ConcurrentHashMap: {Six=6, Four=4, Two=2}
整数集合ConcurrentHashMap: {Six=6, One=1, Four=-4, Two=2}
entrySet()
- 获取 map中key/value 键值对集合keySet()
- 获取map中所有的key的集合values()
- 获取map中所有的value的集合import java.util.concurrent.ConcurrentHashMap;
class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("ConcurrentHashMap: " + numbers);
// 获取 map中key/value 键值对集合
System.out.println("Key/Value mappings: " + numbers.entrySet());
// 获取map中所有的key的集合
System.out.println("Keys: " + numbers.keySet());
// 获取map中所有的value的集合
System.out.println("Values: " + numbers.values());
}
}
输出结果
ConcurrentHashMap: {One=1, Two=2, Three=3}
Key/Value mappings: [One=1, Two=2, Three=3]
Keys: [One, Two, Three]
Values: [1, 2, 3]
get()
- 获取指定key元素的value值,如果key不存在返回nullgetOrDefault()
- 获取指定key元素的value值,如果key不存在返回一个指定的默认值import java.util.concurrent.ConcurrentHashMap;
class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("ConcurrentHashMap: " + numbers);
// 获取指定key元素的value值,如果key不存在返回null
int value1 = numbers.get("Three");
System.out.println("Using get(): " + value1);
// 获取指定key元素的value值,如果key不存在返回一个指定的默认值
int value2 = numbers.getOrDefault("Five", 5);
System.out.println("Using getOrDefault(): " + value2);
}
}
输出结果
ConcurrentHashMap: {One=1, Two=2, Three=3}
Using get(): 3
Using getOrDefault(): 5
remove(key)
- 根据指定的key删除map中的元素,并将该元素返回remove(key, value)
- 只有当map中存在指定的键映射到指定的值时,才会从map中删除条目,并返回一个布尔值。返回true表示删除成功,否则表示map中没有这个键值对。import java.util.concurrent.ConcurrentHashMap;
class Main {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("ConcurrentHashMap: " + numbers);
// 根据指定的key删除map中的元素,并将该元素返回
int value = numbers.remove("Two");
System.out.println("Removed value: " + value);
// 只有当map中存在指定的键映射到指定的值时,才会从map中删除条目,并返回一个布尔值。
boolean result = numbers.remove("Three", 3);
System.out.println("Is the entry {Three=3} removed? " + result);
System.out.println("Updated ConcurrentHashMap: " + numbers);
}
}
输出结果
ConcurrentHashMap: {One=1, Two=2, Three=3}
Removed value: 2
Is the entry {Three=3} removed? True
Updated ConcurrentHashMap: {One=1}