1. 并发Set集合_CopyOnWriteArraySet
较 HashSet 安全!HashSet底层调用的是HashMap的源码,没有锁。
CopyOnWriteArraySet的底层源码带lock.lock();
Set集合的特点:
1.不允许存储重复元素
2.不包含索引的方法
底层源码
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {
// Optimize for lost race to another addXXX operation
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
2. HashTable
Java类库中,从1.0版本也提供一个线程安全的Map:Hashtable
比HashMap 安全
HashTable 不能存null值,HashMap可以存null值。
Hashtable效率低下原因:
public synchronized V put(K key, V value) public synchronized V get(Object key)
Hashtable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下Hashtable的效率非常低下。因为当一个线程访问Hashtable的同步方法,其他线程也访问Hashtable的同步方法时,会进入阻塞状态。如线程1使用put进行元素添加,线程2不但不能使用put方法添加元素,也不能使用get方法来获取元素,所以竞争越激烈效率越低。
HahTable 源码
弊端:
效率太低!
//HahTable 源码
//同步方法,保证了原子操作,确保数据安全
put方法
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();
。。。。。。。。
}
get方法
public synchronized V get(Object key) {
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
return (V)e.value;
}
}
return null;
}
3.
并发Map集合_ConcurrentHashMap
既能兼顾效率,也能保证安全!
属于Map集合里面的实现类对象
HashMap 效率最高,不安全。
HashTable 效率最低,安全,底层源码用的synchronized同步方法代码块,悲观锁。
ConcurrentHashMap 效率较HashTable高,安全!底层源码用的CAS机制,乐观锁,基于循环,重复获取去比较。只对修改的加锁,对于获取和判断,都可以直接操作。