java - 在 Java 中截断同步 ArrayList 的正确方法
问题描述
我有一个 Java ArrayList,一个进程正在用数据填充它:
synchronized (transferredFilesList) {
transferredFilesList.add(transferredFilesDataEvent);
}
我有另一个进程清空这个列表,如果列表中的记录数不超过 2500,它将删除所有条目,但如果条目数大于 2500,它应该截断列表所以删除前 2500 个条目。我正在做这样的截断:
List<LinkedHashMap<String, Object>> tempTransferredFilesList;
synchronized (transferredFilesList) {
logger.info("Transferred files list size: " + transferredFilesList.size());
if(transferredFilesList.size() < 2500){
tempTransferredFilesList = transferredFilesList;
transferredFilesList = new ArrayList<LinkedHashMap<String, Object>>();
}else{
tempTransferredFilesList = new ArrayList<LinkedHashMap<String, Object>>();
tempTransferredFilesList = transferredFilesList.subList(0, 2500);
transferredFilesList = transferredFilesList.subList(2500, transferredFilesList.size());
}
}
但是,每当我超过 2500 条记录时,我都会收到“java.util.ConcurrentModificationException”,这意味着“else”块中的代码不正确。在不逐个迭代和删除元素的情况下截断同步列表的正确方法是什么?
解决方案
你在这里遇到的问题是你正在重新分配你正在同步的东西。一旦你这样做了,synchronized
块就不再在同一个监视器上等待。
处理这个问题的最简单方法是通过截断列表的头部来避免重新分配:
List<T> head = new ArrayList<>(list.subList(0, 2500));
list.subList(0, 2500).clear();
这不会创建一个新列表,它只是将所有内容切到元素 2500。
推荐阅读
- c - 如何在包含预处理器指令中包含 makefile 变量
- javascript - 为什么 Facebook 登录 API 不询问电子邮件访问权限?
- c# - 将 TaskRequestItem 的 UserProperties 传递到 Outlook 应用程序(VSTO 插件)时丢失
- c++ - 如何创建可以包含不同小部件的 QVector 或其他容器?
- android - 启用/禁用 android.nfc.action.TECH_DISCOVERED IntentFilter
- lua - 我在使用 haproxy 中使用 lua 根据查询参数选择后端时遇到问题
- sql - ORACLE SQL - 行名上的通配符
- xcode - 小型集合视图单元格
- r - 我如何在另一个选举半圆中将几年与 plotly 或 ggplot 进行比较?
- flutter - Override gives me an error I cant find the function