队列+线程池消费导致ConcurrentModificationException

505 阅读1分钟
@Autowired
    PieceSearchDao pieceSearchDao;
    public void getInfoFromIntopieces() {
        try{

            List<IntopieceByEagleDTO> list = pieceSearchDao.queryForInsert();
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            List<? extends Callable<String>> lists = Lists.newArrayList();
            List<IntopieceByEagleDTO> dtoList = Lists.newArrayList();
            int index = 1;
            for (IntopieceByEagleDTO intopieceByEagleDTO : list){
                dtoList.add(intopieceByEagleDTO);
                if(index  % 2000 == 0){
                    writeFileLoadFile writeFileLoadFile = new writeFileLoadFile();
                    writeFileLoadFile.setFileName(index);
                    writeFileLoadFile.setIntopieceByEagleDTOS(dtoList);
                    executorService.submit(writeFileLoadFile);
                    dtoList = Lists.newArrayList();
//                    dtoList.clear();
                }
                index++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Data
    class writeFileLoadFile implements Callable<String>{

        private List<IntopieceByEagleDTO> intopieceByEagleDTOS;
        private int fileName;

        @Override
        public String call(){
            try{
                StringBuffer fraudapi = new StringBuffer();
                for(IntopieceByEagleDTO intopieceByEagleDTO : intopieceByEagleDTOS){
                    fraudapi.append(fileName + "\""+intopieceByEagleDTO.getPieces_no_id()+"\",\"413026199008196372\",\"13837132012\",\"1423577433586-67438719\",1,\"Accept\",\"\\N\",\"result\",\"1423577432\",\\N,");
                    fraudapi.append("\r\n");
                }
                FileKit.appendString(fraudapi.toString(),"D:\\aa","utf-8");
            }catch (Exception e){
                e.printStackTrace();
            }
            return "";
        }
    }

报错信息: java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at com.migration.eagle.manager.InsertDataManager$writeFileLoadFile.call(InsertDataManager.java:59)

【问题】:在队列中,产生生产者list,传入消费者线程中,并清空list,同时再进行下一个list的生产,导致在线程中的list获取时,是一点点增加到预定值/直接报错;

【原因】:在用完list后,使用了list.clear();导致此list可能还未被消费,便进行了clear,或者在消费中; 会造成list的并发问题;list的引用传入了线程中,如需重新定义list/list消费后清空,应该是重新定义list;

【解决】:正确处理方法: list.clear(); 改为:——————list = Lists.newArrayList();