大致执行过程:首先获取当前数组存取元素,然后找我们要插入数据的下标值,找到了直接返回false,没找到的话,上锁,再次判断数组是否发生变化,这里多一次判断,我认为是为了防止这种可能性的出现:在判断完是否存在元素和加锁之间,另一个线程加入了我们要加的元素,不判断的话,那么同一个元素就有可能出现俩次,违背了addIfAbsent的意愿。加锁之后,如果数组并没有变的话,那么就执行CopyOnWriteArrayList的老套路,将原来的数据放到一个比原来长度长1的数组,最后一个空位放我们要放的数据。通过上述过程就实现了数据的唯一性,CopyOnWriteSet底层实现就是利用CopyOnWriteArrayList,唯一性就是利用addifabsent方法。

public boolean addIfAbsent(E e) {// 获取元素数组, 取名为快照Object[] snapshot = getArray();// 检查如果元素不存在,直接返回false// 如果存在再调用addIfAbsent()方法添加元素return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :addIfAbsent(e, snapshot);
}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) {// 重新检查元素是否在刚获取的数组里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;}// 拷贝一份n+1的数组Object[] newElements = Arrays.copyOf(current, len + 1);// 将元素放在最后一位newElements[len] = e;setArray(newElements);return true;} finally {// 释放锁lock.unlock();}
}

CopyOnWriteArrayList的addIfAbsent()方法相关推荐

  1. java并发编程——并发容器类介绍

    2019独角兽企业重金招聘Python工程师标准>>> 并发容器的简单介绍 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步 ...

  2. 高并发编程_高并发编程系列:7大并发容器详解(附面试题和企业编程指南)...

    不知道从什么时候起,在Java编程中,经常听到Java集合类,同步容器.并发容器,高并发编程成为当下程序员需要去了解掌握的技术之一,那么他们有哪些具体分类,以及各自之间的区别和优劣呢? 只有把这些梳理 ...

  3. Java集合及concurrent并发包总结(转)

    Java集合及concurrent并发包总结(转) 1.集合包 集合包最常用的有Collection和Map两个接口的实现类,Colleciton用于存放多个单对象,Map用于存放Key-Value形 ...

  4. Java高并发编程:同步工具类

    内容摘要 这里主要介绍了java5中线程锁技术以外的其他同步工具,首先介绍Semaphore:一个计数信号量.用于控制同时访问资源的线程个数,CyclicBarrier同步辅助类:从字面意思看是路障, ...

  5. 终于,我读懂了所有Java集合——set篇

    HashSet (底层是HashMap) Set不允许元素重复. 基于HashMap实现,无容量限制. 是非线程安全的. 成员变量 private transient HashMap<E,Obj ...

  6. Java多线程系列(七):并发容器的原理,7大并发容器详解、及使用场景

    之前谈过高并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 高并发编程系列:CountDownLatch.Semaphore等4大并发工具类详解 高并发编程系列:4大J ...

  7. JUC:ConcurrentHashMap(并发容器)

    JUC:ConcurrentHashMap(并发容器) 关键词 synchronized:并发度,头节点加锁:cas:初始化竞争 / transferIndex多线程扩容进度 sizeCtl(Hash ...

  8. java list 占用内存不释放_Java并发编程 - CopyOnWrite容器类

    前言 当我们对List进行遍历的时候,如果list被修改了会抛出java.util.ConcurrentModificationException错误.那么有没有办法在遍历一个list的时候,还向li ...

  9. 多线程并发知识,肝完这篇10W+字超详细的文章就够了

    大家好,我是Oldou,今天又到了我们的学习时间了,本文介绍的是多线程相关的知识,文中的内容可能不是很全,但是学习完一定会让自己掉发升级,内容比较多,但是我们千万别放弃,不懂的地方一定要主动花时间去理 ...

最新文章

  1. 清华博士找工作7个月没着落,本科学历影响几时休?
  2. mysql创建表的时候不要添加drop操作
  3. Java中float和double精度
  4. 九、WebService中文件传输
  5. cmd中python -V版本显示不出来
  6. 鲁大师检测内存条_外观漂亮,做工精致,潜力巨大、十铨(Team)8GB×2 3200Mhz台式机内存条 火神系列 评测...
  7. redis扫描特定keys脚本,可避免阻塞,不影响线上业务
  8. win10,secoclient总是报错:与对方建立连接超时,配置错误或网络故障
  9. python进行文本分类_python实现文本分类
  10. 商业级web阅读器项目(下下)
  11. OpenCV视频篇——码流 / 码率 / 比特率 / 帧速率 / 分辨率
  12. Epub格式电子书格式
  13. 飞冰,怎么配置打包时候去掉console.log配置
  14. 浅谈泡妞   文 / 中国鄂霸
  15. Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)
  16. 信号完整性设计的五个问题
  17. 一切有迹可循!优秀程序员的9个早期迹象
  18. 计算机不及格检讨书800字,寝室卫生不及格检讨书800字
  19. pdf java解析_JAVA解析PDF内容
  20. String.intern() 的详细理解

热门文章

  1. 深入理解数据结构和算法
  2. B-、B树详解及模拟实现
  3. 【线上分享】华为云RTC服务架构及应用实践
  4. 倒计时5天:5G还是6G?
  5. FFmpeg代码导读——基础篇
  6. 2021博客之星,请帮忙投上宝贵一票
  7. nginx处理http(http变量篇)
  8. PyTorch中的nn.Conv1d与nn.Conv2d
  9. Nexus for linux安装
  10. linux centos 编译Lua5.2.0 静态库 动态库