JAVA 并发类(五) CopyOnWriteArraySet 源码分析
来源:互联网 发布:淘宝网女士夏季服装 编辑:程序博客网 时间:2024/06/05 08:40
1.创建CopyOnWriteArrayList()
2.添加元素 add(E)
3.删除元素 remove(E)
4.遍历对象iterator();
CopyOnWriteArraySet内部使用CopyOnWriteArrayList实现
基本属性:
适合元素不多,读操作较多的并发场合
线程安全
对于add,set,remove这些设计修改的操作比较耗时,因为经常需要复制整个数组
一个线程使用iterator遍历时另一个线程进程remove操作会抛异常(fast fail)
创建
private final CopyOnWriteArrayList<E> al;//底层数据结构public CopyOnWriteArraySet() { al = new CopyOnWriteArrayList<E>();}
内部实际使用CopyOnWriteArrayList实现
添加
添加操作操作调用的是CopyOnWriteArrayList的addIfAbsent方法
public boolean add(E e) { return al.addIfAbsent(e); }
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(); } }
可以看到内部实现主要就是先循环遍历一遍有没有和要插入的值相等的值,如果有直接return,如果没有就进行赋值,保证值的唯一性。
这里可以看到CopyOnWriteArraySet每次add都要遍历数组保证唯一性,因此性能要低于CopyOnWriteArrayList
删除
public boolean remove(Object o) { return al.remove(o);}
也是调用CopyOnWriteArrayList的remove方法
这个之前CopyOnWriteArrayList里说过,分两种情况,第一种删除的元素位于数组中间,那么把删除元素之前的元素复制到新数组中,再把删除元素之后的元素复制到新数组中,再把原数组指向新数组。第二种的要删除的是最后一个元素,那么直接把最后一个元素之前的元素复制到新数组,再把原数组指向新数组即可。
遍历元素
和CopyOnWriteArrayList相同,遍历的时候不支持并发修改否则抛出UnsupportedOperationException。
总结
CopyOnWriteArraySet和CopyOnWriteArrayList的实现大致相同,只是每次add的时候会遍历一遍数组,并且没有按索引直接获取元素的方法。
- JAVA 并发类(五) CopyOnWriteArraySet 源码分析
- 《Java源码分析》:CopyOnWriteArrayList/ CopyOnWriteArraySet
- 《Java源码分析》:CopyOnWriteArrayList/ CopyOnWriteArraySet
- Java并发编程与技术内幕:CopyOnWriteArrayList、CopyOnWriteArraySet源码解析
- 乱弹java并发(三)-- CopyOnWriteArrayList和CopyOnWriteArraySet
- JUC源码分析24-队列-CopyOnWriteArrayList,CopyOnWriteArraySet
- Java 源码分析(五)
- Java并发编程(五)ConcurrentHashMap的实现原理和源码分析
- Java并发编程(五)ConcurrentHashMap的实现原理和源码分析
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- JAVA 并发类(四) CopyOnWriteArrayList 源码分析
- JAVA 并发类(六) ReentrantLock 源码分析
- java 并发包重要类源码分析
- java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍
- Java并发编程系列(五)----ReentrantLock源码解析
- Java多线程--并发中集合的使用之CopyOnWriteArraySet
- Java并发-AtomicInteger源码分析
- 鏖战字符串
- c# 操作Access数据库
- iOS 获取手机型号信息大全
- SQL查询的艺术学习笔记--数据的完整性
- bzoj3698
- JAVA 并发类(五) CopyOnWriteArraySet 源码分析
- QQ点击分享
- 自定义实现简单的ios风格的弹窗加载进度框,一步步走向封装
- Java面向对象复习笔记
- 具有NestedScrollView并且内嵌套RecyclerView,打开页面时不显示在顶部的解决方法
- c语言,空指针,野指针,通用指针
- SQL查询的艺术学习笔记--数据的更新和删除
- 微信公众号 网页授权开发
- codeforces 862B B. Mahmoud and Ehab and the bipartiteness