【源码分析篇】CopyOnWriteArrayList

add()

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();
    }
}
  1. 先去获取锁,若没有获取锁,则阻塞
  2. 将原来的数组拷贝一份,然后在新数组上进行添加操作
  3. 将新数组赋值给旧数组

get()

public E get(int index) {
    return get(getArray(), index);
}
private E get(Object[] a, int index) {
    return (E) a[index];
}

get()方法直接在原数组上面进行操作,所以CopyOnWriteArrayList不会保证数组的实时性,但可以保证数据的最终一致性,它适用于写多读少的场景,如果对数据实时性要求较高的话,不推荐适用CopyOnWriteArrayList。

remove()

public E remove(int index) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        E oldValue = get(elements, index);
        int numMoved = len - index - 1;
        if (numMoved == 0)
            setArray(Arrays.copyOf(elements, len - 1));
        else {
            Object[] newElements = new Object[len - 1];
            System.arraycopy(elements, 0, newElements, 0, index);
            System.arraycopy(elements, index + 1, newElements, index,
                             numMoved);
            setArray(newElements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}
  1. 和add()方法一样,remove方法也是先获取锁,没有则阻塞
  2. 获取到锁了则判断当前元素下标是否为最后一个元素,若为最后一个元素,则只需要进行一次数组拷贝即可,若不是,则需要进行两次数组拷贝,分别是该元素前半部分和该元素后半部分。
  3. 最后再给源数组赋值。

    鄙人新开设的模块,之后会将微信公众号【An前码后】中的文章陆续搬迁到牛客网,若想阅读更多的源码解析,请关注微信公众号【An前码后】

#Java源码##学习路径#
全部评论

相关推荐

一面整体流程挺短的,34分钟就开始手撕,撕完就结束了,常规八股,难度不大面试官介绍到店部门自我介绍(要求从技术栈、项目经历说起)说一说在美团实习中你参与的比较完整的项目或需求有没有什么亮点或难点你们项目用的是同步还是异步,为什么补偿机制怎么做场景题:线上机器出现大量GC.count,如何排查和处理,首先应该做什么HashMap与HashSet的底层实现与区别说一说JVM的内存区域多线程什么时候会扩展到最大线程数线上使用多线程时应该注意什么AOP的使用场景和原理MySQL怎么保证事务的四个特性的手撕SQLhard lc124 二叉树的最大路径和反问二面二面全程拷打项目细节与场景题,全程0八股,时长1h压力面,面试官一直在追问细节,一直在出场景,不停出招换招。。80%都是围绕我实习项目来的,分享一些共性的问题吧手撕三表联查的SQLlc 最接近的三数之和看过哪些源码我说集合看的多一点,面试官说不要说集合(哭)我说AQS和ReentrantLock也看过一点,面试官说好那你说说吧,硬着头皮说,期间也没少被追问然后被吐槽平时源码看的比较少啊,,(我。。。确实)那你平时怎么学习的?最近在看什么技术类书籍我说MySQL45讲,他两眼放光问是极客时间上的吗,我心想坏了,他也看过。。问我看了哪些,我硬着头皮说了一些。。。你觉得什么样的代码是好代码你写的代码哪里好哪里不好说一说具体用过什么设计模式,简单说说怎么用的我先说了模板模式,简单说了说场景,追问除了模板模式呢我又说了策略模式,也说了说场景,继续追问除了策略模式呢我再说了代理模式和场景,继续逼问我说项目中的单例,面试官继续问,我说其他我就只是了解没有在实际项目中使用过了⏰【美团】25届校招招聘正式启动!【招聘岗位】技术类、产品类、运营类、职能类、金融类、设计类、零售类等【工作城市】北京、上海、深圳、广州等诸多可选城市【招聘对象】25届毕业生(70%可留用,相当于25届提前批)内推码:XM33NKU内推链接:https://zhaopin.meituan.com/web/campus(在投递界面右上方填写内米哈游推码,可免除简历初筛,直接进入笔/面试环节!同时本人提供流程跟进服务~)【特别说明】本次招聘计划的HC很多,欢迎大家踊跃投递!投递的uu评论一下姓名缩写加岗位(HFG+产品经理),我会尽力跟进~
美团
|
校招
|
超多精选岗位
点赞 评论 收藏
分享
10-08 19:22
已编辑
门头沟学院 Java
#软件开发笔面经#timeline 2024/9/8号1.自我介绍2.java常见集合有哪些3.LinkedList和ArrayList的区别,(适用场景还需深究?)4.hashMap底层了解吗(加入红黑树的原因有哪些,除了查询速度)5.hashMap默认因子,默认长度,以及扩容时候会不会再哈希6.ThreadLocal了解吗,以及原理7.线程池如果在持续工作,下一个进来的线程会拿到上一个线程的数据吗8.常用的线程池有哪些9.线程池的几大参数,以及抛弃策略具体有哪些10.了解Mysql索引吗11.场景题:A,B,C创建联合索引, where A=“”and C="" and  B="",会怎么走索引(这个按道理不会走全部索引,当时mysql自己会进行优化,所以会走全部索引!)12.forUpdate 和show lock on .....是什么(锁那一块)13.Mysql如何对一行数据加锁14.explain了解吗15.实习的时候有慢sql的优化经验16.分页处理  1.select .. limit a,b 和主键索引加子查询,什么情况某个优势更显著(有瓶颈)17.mysql事务隔离级别18.linux常见命令,知道linux里面文件是有用户和用户组的概念吗19.什么命令怎么一下创建多件不存在的文件夹20.拥塞控制了解吗21.http的常见状态码22.三次握手,四次挥手了解吗,以及每个阶段的状态名称比如什么wait_establish23.握手过程,一方最多等待多久(两倍的报文最大数)24.tcp,http都分别处在那一层25.jvm垃圾回收算法有哪些26.常见的垃圾回收器27.CMS和G1的区别28.讲讲spring的ioc和aop,你们一般会aop干嘛29.切点和切面有什么区别30.@AutoWird是如何加载一个类的31.Bean的生命周期32.spring的单例Bean是线程安全的吗33.redis的淘汰策略34.如何解决缓存雪崩35.算法题:(秒了!)给定一个已排序的链表的头head, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表1->2->2->3->3->4->5 1->4->5反问:多久出结果公司项目是什么,框架是什么建议,评价hhhhh说八股背的挺6,难绷,还是建议多一点自己的理解当场约二面了 学到了一些东西,比如16点和11点  还需改进的:6,7,12,13,18,19,20,22,23,27,30二面 自我介绍实现拷打RabbitMQ了解吗,优点,缺点如何保证MQ的数据可靠性分布式的事务一致性如何保证Spring了解吗说说看,springboot了解吗Springboot中的核心注解了解吗Yml,yaml,proprities了解吗如何学习一个新的技术栈未来规划操作系统:父子进程如何切换(寄)操作系统:线程组了解吗(寄)#软件开发笔面经#
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务