本帖最后由 w837956 于 2015-02-03 20:53:43 编辑

解决方案 »

  1.   

    仅仅这点代码肯定无法确定问题所在,不过可能性最大的就是多线程导致的,ArrayList本身并非线程安全的,建议自己实现一个线程安全的List,在你自己实现的List中可以使用ArrayList来保存数据,只是对add,addall等方法进行同步控制。
      

  2.   

    试试Collections.synchronizedList(List<T> list)
      

  3.   


    我觉得问题应该不在楼主贴出来的部分,而是在省略号之后的部分如果多线程导致的话,楼主的debug出来的就不是那个样子了。
      

  4.   

    synchronized (this.clientAnalysisBeansList) {
                this.clientAnalysisBeansList.addAll(clientAnalysisBeansList);
     }
    这是给List扩容吗?
      

  5.   


    我觉得问题应该不在楼主贴出来的部分,而是在省略号之后的部分如果多线程导致的话,楼主的debug出来的就不是那个样子了。省略号之后的部分是sql语句,没必要贴出来,debug后在catch中找到当前for循环的 i  然后看list 发现上面图的结果
      

  6.   


    合并多线程中返回的list 用事务更新到数据库中
      

  7.   


    自己实现list还是一样的加锁做同步,我在执行addAll时加了锁也是不行的,有时候半天都不会出这个问题,有时候一会就会出现好几次,我主要是想知道为什么会出现下标跳跃的问题,(理论上我直接用vector应该可以避免) 难道是ArrayList在执行arraycopy的时候出现的问题?下标少一个,但是看list的size还是够的,,,好奇怪
      

  8.   


    自己实现list还是一样的加锁做同步,我在执行addAll时加了锁也是不行的,有时候半天都不会出这个问题,有时候一会就会出现好几次,我主要是想知道为什么会出现下标跳跃的问题,(理论上我直接用vector应该可以避免) 难道是ArrayList在执行arraycopy的时候出现的问题?下标少一个,但是看list的size还是够的,,,好奇怪我昨天后来看了一下ArrayList的源代码。最大的可能还是你别的地方还有对 this.clientAnalysisBeansList 的操作导致的。要解决这个问题也很简单,你还是用local的变量再new 一个 ArrayList,然后把类变量里的clientAnalysisBeansList并到新的ArrayList里,然后再进行操作。最后再用同步块,把类变量的clientAnalysisBeansList清空,把你新的ArrayList再addAll进来。
      

  9.   


    Collections.synchronizedList 和 Vector暂时都没有在出现过跳下标的问题
      

  10.   


    Collections.synchronizedList 和 Vector暂时都没有在出现过跳下标的问题[/qu
    但是还是不知道为什么会跳下标
      

  11.   


    自己实现list还是一样的加锁做同步,我在执行addAll时加了锁也是不行的,有时候半天都不会出这个问题,有时候一会就会出现好几次,我主要是想知道为什么会出现下标跳跃的问题,(理论上我直接用vector应该可以避免) 难道是ArrayList在执行arraycopy的时候出现的问题?下标少一个,但是看list的size还是够的,,,好奇怪我昨天后来看了一下ArrayList的源代码。最大的可能还是你别的地方还有对 this.clientAnalysisBeansList 的操作导致的。要解决这个问题也很简单,你还是用local的变量再new 一个 ArrayList,然后把类变量里的clientAnalysisBeansList并到新的ArrayList里,然后再进行操作。最后再用同步块,把类变量的clientAnalysisBeansList清空,把你新的ArrayList再addAll进来。
    在所有线程返回以前是没有对 this.clientAnalysisBeansList 的操作的,(我刚检查了代码)
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(
            "Index: " + index + ", Size: " + size);    Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);  // Increments modCount    int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                     numMoved);        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
        }
    我认为最大的可能性就是在上面的arraycopy产生的,
    一个线程返回数据后list执行addAll,同时另外一个线程返回了,也去执行这个addAll,这个方法没有线程互斥,很容易出问题
    但是后面我对他加锁了,还是会出现跳下标的这种奇葩问题,,,我没法证明问题肯定出在这里,,,所以很纠结,,,
      

  12.   


    自己实现list还是一样的加锁做同步,我在执行addAll时加了锁也是不行的,有时候半天都不会出这个问题,有时候一会就会出现好几次,我主要是想知道为什么会出现下标跳跃的问题,(理论上我直接用vector应该可以避免) 难道是ArrayList在执行arraycopy的时候出现的问题?下标少一个,但是看list的size还是够的,,,好奇怪我昨天后来看了一下ArrayList的源代码。最大的可能还是你别的地方还有对 this.clientAnalysisBeansList 的操作导致的。要解决这个问题也很简单,你还是用local的变量再new 一个 ArrayList,然后把类变量里的clientAnalysisBeansList并到新的ArrayList里,然后再进行操作。最后再用同步块,把类变量的clientAnalysisBeansList清空,把你新的ArrayList再addAll进来。
    在所有线程返回以前是没有对 this.clientAnalysisBeansList 的操作的,(我刚检查了代码)
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(
            "Index: " + index + ", Size: " + size);    Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);  // Increments modCount    int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                     numMoved);        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
        }
    我认为最大的可能性就是在上面的arraycopy产生的,
    一个线程返回数据后list执行addAll,同时另外一个线程返回了,也去执行这个addAll,这个方法没有线程互斥,很容易出问题
    但是后面我对他加锁了,还是会出现跳下标的这种奇葩问题,,,我没法证明问题肯定出在这里,,,所以很纠结,,,
    那就别纠结跳下标的问题了。按我给你的建议做,多个三五行代码而已
      

  13.   


    自己实现list还是一样的加锁做同步,我在执行addAll时加了锁也是不行的,有时候半天都不会出这个问题,有时候一会就会出现好几次,我主要是想知道为什么会出现下标跳跃的问题,(理论上我直接用vector应该可以避免) 难道是ArrayList在执行arraycopy的时候出现的问题?下标少一个,但是看list的size还是够的,,,好奇怪我昨天后来看了一下ArrayList的源代码。最大的可能还是你别的地方还有对 this.clientAnalysisBeansList 的操作导致的。要解决这个问题也很简单,你还是用local的变量再new 一个 ArrayList,然后把类变量里的clientAnalysisBeansList并到新的ArrayList里,然后再进行操作。最后再用同步块,把类变量的clientAnalysisBeansList清空,把你新的ArrayList再addAll进来。
    在所有线程返回以前是没有对 this.clientAnalysisBeansList 的操作的,(我刚检查了代码)
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(
            "Index: " + index + ", Size: " + size);    Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);  // Increments modCount    int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                     numMoved);        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
        }
    我认为最大的可能性就是在上面的arraycopy产生的,
    一个线程返回数据后list执行addAll,同时另外一个线程返回了,也去执行这个addAll,这个方法没有线程互斥,很容易出问题
    但是后面我对他加锁了,还是会出现跳下标的这种奇葩问题,,,我没法证明问题肯定出在这里,,,所以很纠结,,,
    那就别纠结跳下标的问题了。按我给你的建议做,多个三五行代码而已恩,谢谢结贴散分