list集合数据丢失问题

知识串讲

1ASPL多线程实现方案

 

主线程控制任务是否结束  

 

  1:首先判断当前任务是否完成  while true     ---当前任务(excel name)是否所有任务数据状态是否为compete(比较结束更新的状态)  若完成   break

  

  2:没完成  获取当前运行的任务数  和最大任务数比较  判断是否需要开启新任务

  

  3:需要开启  从数据库获取一定数量数据   首先批量更新数据状态为running  

  4:通过循环将每一条数据和六个arraylist(作用收集比较结果)作为一个线程的参数传入线程类(自己封装的)  然后让将这个线程对象交给线程池执行

  

  5;线程类主要是通过sheetName 来判断需要调用拿个方法和使用哪个list来收集数据    比较方法执行结束后  将这条数据状态更新为complete

 

 

2:结果数据丢失问题

 

  现象:偶先问题 生成的报告结果中偶尔会丢失1-2条数据

 

  原因分析:查看日志发现 在偶先会ArrayIndexOutOfBoundsException  经分析此异常是在

执行Arraylistadd方法时抛出的  查看其源码其核心代码基本流程为添加元素之前首先判断此数组是否需要扩容---->如需要先扩容--->然后执行 elementData[size++] = e;

    public boolean add(E e) {

      // 判断列表的capacity容量是否足够,是否需要扩容

        ensureCapacityInternal(size + 1);  // Increments modCount!!

 

        // 将元素添加进列表的元素数组里面

      elementData[size++] = e;

          return true;

    }

 

由于我们的每一个sheet页数据最终时被收集到同一个List当中,执行add方法,由以上代码可得知  此方法是非安全方案(未加锁或同步处理)。故多线程执行时会出现两种可能性   

1):数据被覆盖(导致部分数据丢失)

      非扩容期间,首先执行elementData[size++] = e;   然后执行size++  在这两步之间

可能执行另外一个add操作  故会发生数据覆盖

 

 

2)add时数组越界直接抛出异常  (扩容期间)

     

 

 

修改方案:使用安全的LIST   Collections.synchronizedList

 

   

posted @ 2020-09-07 19:10  春意了无痕  阅读(1807)  评论(0)    收藏  举报