有 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”块中的代码不正确。在不逐个迭代和删除元素的情况下,截断同步列表的正确方法是什么


共 (1) 个答案

  1. # 1 楼答案

    这里的问题是,您正在重新分配正在同步的对象。一旦这样做,synchronized块就不再在同一个监视器上等待

    处理这一问题的最简单方法是通过截断列表的开头来避免重新分配:

    List<T> head = new ArrayList<>(list.subList(0, 2500));
    list.subList(0, 2500).clear();
    

    这并不会创建一个新的列表,它只是将所有内容切碎到元素2500