ConcurrentHashMap:
支持检索的完全并发和更新的所期望可调整并发的哈希表。此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有操作都是线程安全的,但检索操作不 必锁定,并且不 支持以某种
防止所有访问的方式锁定整个表。此类可以通过程序完全与 Hashtable 进行互操作,这取决于其线程安全,而与其同
步细节无关
简单说,ConcurrentHashMap是线程安全,用法和HashMap差不多
不过ConcurrentHashMap的性能比Collections.synchronizedMap(new HashMap<>)快的多例如下面的例子
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 测试HashMap和ConcurrentHashMap的并发性能差别。
*
* @author 老紫竹 JAVA世纪网(java2000.net)
*
*/
public class FinalMain {
static final int threads = 1000;
static final int NUMBER = 1000;
public static void main(String[] args) throws Exception {
Map<String, Integer> hashmapSync = Collections
.synchronizedMap(new HashMap<String, Integer>());
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<String, Integer>();
Map<String, Integer> hashtable = new Hashtable<String, Integer>();
long totalA = 0;
long totalB = 0;
long totalC = 0;
for (int i = 0; i <= 10; i++) {
totalA += testPut(hashmapSync);
totalB += testPut(concurrentHashMap);
totalC += testPut(hashtable);
}
System.out.println("Put time HashMapSync=" + totalA + "ms.");
System.out.println("Put time ConcurrentHashMap=" + totalB + "ms.");
System.out.println("Put time Hashtable=" + totalC + "ms.");
totalA = 0;
totalB = 0;
totalC = 0;
for (int i = 0; i <= 10; i++) {
totalA += testGet(hashmapSync);
totalB += testGet(concurrentHashMap);
totalC += testGet(hashtable);
}
System.out.println("Get time HashMapSync=" + totalA + "ms.");
System.out.println("Get time ConcurrentHashMap=" + totalB + "ms.");
System.out.println("Get time Hashtable=" + totalC + "ms.");
}
public static long testPut(Map<String, Integer> map) throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < threads; i++) {
new MapPutThread(map).start();
}
while (MapPutThread.counter > 0) {
Thread.sleep(1);
}
return System.currentTimeMillis() - start;
}
public static long testGet(Map<String, Integer> map) throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < threads; i++) {
new MapPutThread(map).start();
}
while (MapPutThread.counter > 0) {
Thread.sleep(1);
}
return System.currentTimeMillis() - start;
}
}
class MapPutThread extends Thread {
static int counter = 0;
static Object lock = new Object();
private Map<String, Integer> map;
private String key = this.getId() + "";
MapPutThread(Map<String, Integer> map) {
synchronized (lock) {
counter++;
}
this.map = map;
}
public void run() {
for (int i = 1; i <= FinalMain.NUMBER; i++) {
map.put(key, i);
}
synchronized (lock) {
counter--;
}
}
}
class MapGetThread extends Thread {
static int counter = 0;
static Object lock = new Object();
private Map<String, Integer> map;
private String key = this.getId() + "";
MapGetThread(Map<String, Integer> map) {
synchronized (lock) {
counter++;
}
this.map = map;
}
public void run() {
for (int i = 1; i <= FinalMain.NUMBER; i++) {
map.get(key);
}
synchronized (lock) {
counter--;
}
}
}
运行结果
Put time HashMapSync=3949ms.
Put time ConcurrentHashMap=1143ms.
Put time Hashtable=3396ms.
Get time HashMapSync=3861ms.
Get time ConcurrentHashMap=1029ms.
Get time Hashtable=3409ms.