CopyOnwriteArrayList
ArrayList的问题:ConcurrentModificationException 并发修改异常
public class CopyonwriteArraylist_Test {
public static void main(String[] args) {
List<String > list=new ArrayList();
for (int i=0 ;i<=10 ;i++){
new Thread(()->{list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list); },String.valueOf(i)).start();
}
}
}
复制代码
解决方案:
- List list=new Vector();
- List list=Collections.synchronizedList();
- List list=new CopyOnWriteArrayList<>();
为什么CopyOnWriteArrayList可以保证线程安全
public boolean add(E e) {
final ReentrantLock lock = this.lock; //通过ReentrantLock保证只有一个线程进行修改
lock.lock();
try {
// 写时复制
Object[] elements = getArray();//获取旧数组
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);//创建一个len+1的新数组,并将旧数组copy过来
newElements[len] = e; //在新数组末尾添加新元素
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
@SuppressWarnings("unchecked")
// 读不加锁
private E get(Object[] a, int index) {
return (E) a[index];
}
复制代码
优缺点
- CopyOnWrite容器,写时复制,是读写分离的思想。
- 读的时候不加锁,可以并发的读,提高并发性
- 只有在修改或删除的时候加锁,并且是对新数组进行操作不影响读
- 由于读不加锁,所以有可能在读的时候有线程对数据进行修改,因而读的是旧数据,即弱一致性
- 占用内存,在写的时候会创建新对象添加到新容器里,而旧容器的对象还在使用,所以有两份对象内存。内存占用大时,可考虑ConcurrentHashMap
与Vector的区别
- Vector 是粗暴的加synchronized,并发性低,CopyOnWrire只在修改的时候加锁,读的操作性高
CopyOnwriteArraySet
- HashSet 本质是Hash Map的key,利用hashmap的key来保证唯一,同时也导致了无序。
- CopyOnwriteArraySet 却是调用CopyOnwriteArrayList来实现的。
public HashSet() {
map = new HashMap<>();
}
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
复制代码
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();
}
public boolean add(E e) {
return al.addIfAbsent(e);
}
复制代码
ConcurrentHashMap
- HashMap 是线程不安全的
- HaspTable 是线程安全的,但是简单粗暴的加synchronized,效率低下
ConcurrentHashMap
参考:zhuanlan.zhihu.com/p/31614308
ConcurrentHashMap维护一个segments数组如下,可以说,ConcurrentHashMap是一个二级哈希表。在一个总的哈希表下面,有若干个子哈希表。
- 不同的Segment拥有不同的锁,在保证线程安全的同时降低了锁的粒度,让并发操作效率更高。
- 同一个Segment读不加锁,写才加锁
- 1.8之后直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用内置Synchronized和CAS来操作,一把锁只锁住一个链表。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END