gpt4 book ai didi

java - LinkedList并发修改异常

转载 作者:行者123 更新时间:2023-12-01 06:54:13 35 4
gpt4 key购买 nike

我正在寻找一种好方法来构建有限链表。如果链表已“满”,则将删除第一个元素并添加新元素。所以我总是拥有“最新”“限制大小”元素。

这是通过以下方式实现的:

    private int maxSize;

public LimitedLinkedList(int maxSize) {
this.maxSize = maxSize;
}

@Override
public synchronized boolean add(E object) {
boolean success = super.add(object);
while (this.size() >= maxSize) {
removeFirst();
}
return success;
}

现在我有以下问题:我需要计算链表的平均值。这时候,我随机得到并发修改异常或索引越界异常。我的平均方法:

public synchronized static double movingAverage(
LinkedList<AverageObject> valueList) {
if (valueList.isEmpty()) {
return 0;
}
double sum = 0;

int m = 0;
for (int i = 0; i < valueList.size(); i++) {
AverageObject object= valueList.get(i);
sum += object.value;
m++;
}

sum = (m != 0) ? sum / m : sum;
return sum;
}

你知道避免并发修改异常的好方法吗?

我唯一的想法是,每次列表更改时计算平均值,这样当我想要平均值时,我不必迭代它。

最佳答案

并发修改问题其实和你对add的修改无关。如果您在计算平均值时添加了一个元素,那么常规的 LinkedList 也会发生这种情况。您所展示的代码根本无法生成 ConcurrentModificationException ,这也是毫无值(value)的。 (但它可能会给出越界异常......)

您遇到问题的最可能原因是您的 addmovingAverage 方法未正确同步:

  • synchronized 实例方法锁定目标对象;即列表实例。
  • 静态同步方法会锁定该方法的声明类的Class对象;即声明 movingAverage 方法的类。

如果两个线程不锁定同一个对象,它们将不会同步,并且不会出现互斥。这意味着 addmovingAverage 可能会同时读取和更新同一个列表......导致异常(或更糟)。

避免这些问题的一种方法可能是将 movingAverage 方法更改为:

public static double movingAverage(
LinkedList<AverageObject> valueList) {
synchronized (valueList) {
...
}
}

甚至是这个:

public synchronized doubkle movingAverage() {
...
}

然而,这都是零碎的。更好的方法可能是在更高级别进行同步,或者使用“并发”数据结构来避免显式同步。

关于java - LinkedList并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16541309/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com