需求就是因为数据量过大,就实现一个类似于异步分批计算,最后再取回合并的功能。
但是直接使用subList,发现原数组的值被改了,简单的分析了一下代码。
1 2
| tempList = list.subList(0, batchNumber); tempList.clear();
|
是因为我对截取的List进行了清空处理,导致原List改变了,由此处也可知subList其实是指向了原List截取的部分,如果对他清除了,原List也就会改变了。
发现了这个原因,实现一个分批的功能就简单多了。
分批计算的是项目中的,比较复杂。
我下面以分批保存数据库为例,复现一下这个问题,这是一个完整的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
private void batchSaveSync(List<Student> list) { int slice = slice(list.size(), batchNumber); for (int i = 0; i < slice; i++) { List<Student> tempList; if (batchNumber > list.size()) { tempList = list.subList(0, list.size()); } else { tempList = list.subList(0, batchNumber); } crudRepository.saveAll(tempList); tempList.clear(); } }
private void batchSaveAsync(List<Student> list) { ExecutorService executorService = new ExecutorConfig().executorService(); int slice = slice(list.size(), batchNumber); for (int i = 0; i < slice; i++) { List<Student> tempList; if (batchNumber > list.size()) { tempList = list.subList(0, list.size()); } else { tempList = list.subList(0, batchNumber); } BatchSaveCallable callable = new BatchSaveCallable(tempList); executorService.submit(callable); tempList.clear(); } }
private Integer slice(int size, int batchNumber) { return (size - 1) / batchNumber + 1; }
|
源码meethigher/batch-save: batch-save