通过并发容器来改善同步容器的性能,同步容器将所有对容器状态的访问都串行化,来实现线程安全,这种方式严重降低并发性,当多个线程访问时,吞吐量严重降低。
并发容器ConcurrentHashMap
替代同步基于散列的Map,通过Lock控制。
原理锁分段,用new object[16]中每个元素作为一个锁,然后用synchronized(object[hash(key)%16])进行同步。
ConcurrentMap接口中增加了一些常见的复合操作的支持。对ConcurrentHashMap进行迭代不会抛出异常(弱一致性)。size,isEnptry这些方法的语意被减弱了以反映容器的并发特性,还包括(get、put、containsKey、remove)
public interface ConcurrentMap<K, V> extends Map<K, V> {
//仅当key没有相应的映射值时才插入
V putIfAbsent(K key, V value);
//仅当key被映射到value时才被删除
boolean remove(Object key, Object value);
//仅当key被映射到oldvalue时才被替换为newvalue
boolean replace(K key, V oldValue, V newValue);
//仅当key被映射到某个值时才替换为value
V replace(K key, V value);
}
并发队列(ConcurrentLinkedQueue)和阻塞队列(LinkedBlockingQueue)
- ConcurrentLinkedQueue:是无阻塞的队列,可伸缩性比BlockingQueue高,采用CAS模式BlockingQueue(Lock)扩展了Queue 增加了可阻塞插入和获取等操作(Lock)。阻塞队列支持可阻塞的put和take,以及支持定时的offer和poll方法(如果数据不能添加到队列中,那么将返回一个失败的状态,这样就能灵活处理复合过载的情况,例如减轻负载,将多余的的工作项序列化写入磁盘,减少生产者线程数量)。其实现类LinkedBlockQueue和ArrayBlockingQueue是FIFO队列,二者与LinkedList和ArrayLsit相似,但比同步List拥有更好的并发性。PriorityBlockingQueue是一个按优先级排序的队列。
CopyOnWriteArrayList、CopyOnWriteArraySet(判断)、(Lock)
CopyOnWriteArraySet:底层就是CopyOnWriteArrayList,不过多了一步去重的工作
CopyOnWriteArrayList用在遍历操作为主要操作的情况下代替同步的List,紧当迭代操作远远多余修改操作时,才应使用“写入时复制”容器
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
并发的树形结构
- ConcurrentSkipListMap替代同步的SortedMap采用CAS模式
- ConcurrentSkipListSet替代同步的SortedSet采用CAS模式