• 阿里面试问题总结 ArrayList


    1  ArrayList是线程安全的吗?

    2 多线程情况下往ArrayList里面添加元素,会导致什么问题?

    源码分析

    
    
    public boolean add(E e) {
    //检测长度并扩容 ensureCapacityInternal(size + 1); // Increments modCount!!
    //元素放到 size位置 并使size=size+1 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    //数组为空,给个默认值10 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }

    根据上面执行流程,其实我们很容器发现问题的所在,其实就是最后这一行代码elementData[size++] = e;导致。添加一个元素我们可以理解为:

    1. 在 elementData[Size] 的位置存放此元素;
    2. 增大 Size 的值。
    我们分别使用两个线程来模拟插入过程.例如有两个线程,分别加入数字1与2.

     运行的过程如下所示:
    1、线程1 赋值 element[1] = 1; 随后因为时间片用完而中断; 此时size = 1
    2、线程2 赋值 element[1] = 2; 随后因为时间片用完中断;  此时size = 1

    此处导致了之前所说的一个问题(有的线程没有输出); 因为后续的线程将前面的线程的值覆盖了,导致了值被覆盖问题

    3、线程1 自增 size++; (size=2)
    4、线程2 自增 size++; (size=3)

    此处导致了某些节点值为null的问题。 因为原size=1, 但是因为线程1与线程2都将值赋值给了element[1],导致了element[2]内没有值,被跳过了,

    指针index指向了3.所以,导致了某些情况下值为null的情况,可能在获取它进行计算的时候报了空指针异常。

    导致了数组越界问题

     前提条件: 当前size=1 数组长度为3 (下标有  0,1,2)

    1、线程1 判断数组是否越界.因为size=2 长度为3,没有越界.将进行赋值操作.但是因为时间片问题导致了中断.

    2、线程2 判断数组是否越界.因为size=2 长度为3,没有越界.将进行赋值操作.但是因为时间片问题导致了中断.

    3、线程1 重新获取到主动权.上文判断了长度刚刚好够用.进行赋值操作element[size]=1,并且size++  此时size=3

    4、线程2 因为上文判断了数组没有越界.所以进行赋值操作.但是此时的size=3了.再执行element[3]=2. 导致了数组越界了(因为本身数组长度是3,最大索引只能是2)

  • 相关阅读:
    第七章 路由 68 路由-前端路由和后端路由的概念
    第六章 组件 67 使用ref获取DOM元素和组件引用
    第六章 组件 65-66 组件案例-发表评论功能的实现
    第六章 组件 63 组件传值-父组件向子组件传值和data与props的区别
    第六章 组件 62 组件-组件定义方式的复习
    第六章 组件 61 动画-小球动画flag标识符的作用分析
    第六章 组件 60 组件切换-应用切换动画和mode方式
    第六章 组件 59 组件切换-使用Vue提供的component元素实现组件切换
    vscode代码格式化 空格的配置
    vim配置C++开发环境 win10
  • 原文地址:https://www.cnblogs.com/hup666/p/13449513.html
Copyright © 2020-2023  润新知