这段代码有没有问, lockFailBillList.removeAll(batch);可以在循环中remove吗? private List<Bill> retryLockingBills(List<Bill> bills, String projectId, PropertyUser propertyUser) { int[] BATCH_SIZES = {100, 50, 10, 1}; List<Bill> lockFailBillList = new ArrayList<>(bills); for (int batchSize : BATCH_SIZES) { List<List<Bill>> batchBillList = Lists.partition(lockFailBillList, batchSize); for (List<Bill> batch : batchBillList) { try { billTagApplyService.lockOrUnlockBill(batch, projectId, true, LockTypeEnum.LOCK_TYPE_ENUM_16.getCode(), propertyUser, true); //锁定成功则将该批账单从失败账单列表中删除 lockFailBillList.removeAll(batch); } catch (Exception e) { //锁定失败继续执行下一批 } } } return lockFailBillList; }
时间: 2024-02-14 18:28:37 浏览: 79
在循环中使用 `lockFailBillList.removeAll(batch)` 可能会导致 `ConcurrentModificationException` 异常。这是因为在遍历 `lockFailBillList` 的同时,我们试图修改它。
为了避免此问题,一种解决方案是在循环结束后创建一个新的列表,将成功锁定的账单从原始列表中移除,并返回新列表。以下是修改后的代码示例:
```java
private List<Bill> retryLockingBills(List<Bill> bills, String projectId, PropertyUser propertyUser) {
int[] BATCH_SIZES = {100, 50, 10, 1};
List<Bill> lockFailBillList = new ArrayList<>(bills);
List<Bill> successfullyLockedBills = new ArrayList<>();
for (int batchSize : BATCH_SIZES) {
List<List<Bill>> batchBillList = Lists.partition(lockFailBillList, batchSize);
for (List<Bill> batch : batchBillList) {
try {
billTagApplyService.lockOrUnlockBill(batch, projectId, true, LockTypeEnum.LOCK_TYPE_ENUM_16.getCode(), propertyUser, true);
successfullyLockedBills.addAll(batch); // 将成功锁定的账单添加到新列表中
} catch (Exception e) {
// 锁定失败继续执行下一批
}
}
lockFailBillList.removeAll(successfullyLockedBills); // 从原始列表中移除成功锁定的账单
successfullyLockedBills.clear(); // 清空成功锁定的账单列表
}
return lockFailBillList;
}
```
在上述修改中,我们创建了一个新的列表 `successfullyLockedBills`,用于保存成功锁定的账单。在每个批次大小的循环中,如果账单成功锁定,我们将其添加到 `successfullyLockedBills` 列表中。在每个批次大小循环结束后,我们使用 `lockFailBillList.removeAll(successfullyLockedBills)` 语句从原始列表中移除成功锁定的账单,然后清空 `successfullyLockedBills` 列表。
这样做可以避免在循环中修改正在遍历的列表,从而避免 `ConcurrentModificationException` 异常。
希望这次的解答对你有帮助!如果你还有其他问题,请随时提问。
阅读全文