ArrayList,HashMap都是非线程安全的类,因此在多线程中不能使用。
那么多线程下如果要使用集合或map类型怎么办呢?当然是有别的替代类,比如HashMap要选用HashTable或ConcurrentHashMap,而ArrayList则要选用Vector或CopyOnWriteArrayList。
HashTable和ConcurrentHashMap
两者的区别就是HashTable是完全基于synchronized锁实现的同步,而ConcurrentHashMap则是CAS+volatile和synchronized结合使用的,效率要比HashTable高。所以在多线程中对于Map类型通常优先使用ConcurrentHashMap。
Vector和CopyOnWriteArrayList
Vector也是完全基于synchronized锁实现的同步。CopyOnWriteArrayList看名字就知道使用的是CopyOnWrite的实现方式。所以多线程情况下,如果是读多写少或无锁读的场景下通常优先使用CopyOnWriteArrayList。
CopyOnWrite之前写过概念。CopyOnWriteArrayList中数组是volatile的,CopyOnWriteArrayList的读操作完全无锁,而写操作使用复制副本+lock锁实现线程安全。
需要注意的是CopyOnWriteArrayList每次写操作都会复制数组副本,因此不适合频繁写操作的场景。
//get读操作
private E get(Object[] var1, int var2) {
return var1[var2];
}
public E get(int var1) {
return this.get(this.getArray(), var1);
}
//add写操作
public boolean add(E var1) {
ReentrantLock var2 = this.lock;
var2.lock();
boolean var6;
try {
Object[] var3 = this.getArray();
int var4 = var3.length;
Object[] var5 = Arrays.copyOf(var3, var4 + 1);
var5[var4] = var1;
this.setArray(var5);
var6 = true;
} finally {
var2.unlock();
}
return var6;
}