【问题标题】:Why set(int index, E element) function in CopyOnWriteArrayList is so fussy?为什么 CopyOnWriteArrayList 中的 set(int index, E element) 函数如此繁琐?
【发布时间】:2016-03-15 15:50:01
【问题描述】:

源码在这里:

public E set(int index, E element) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        E oldValue = get(elements, index);

        if (oldValue != element) {
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len);
            newElements[index] = element;
            setArray(newElements);
        } else {
            // Not quite a no-op; ensures volatile write semantics
            setArray(elements);
        }
        return oldValue;
    } finally {
        lock.unlock();
    }
}

但我认为if-else 块可以更简洁如下:

if (oldValue != element) {
    elements[index] = element;
}

请帮我解决这个问题,在此先感谢。

【问题讨论】:

  • @MarounMaroun 但似乎所有函数都使用lock,所以我认为线程安全应该不是问题。
  • 有关 COWAL.set() 为何以这种方式编码的更多信息,请参阅stackoverflow.com/a/28777239/1441122

标签: java data-structures collections


【解决方案1】:

正如类名所暗示的,该类执行底层数据结构(即数组)的写入时复制。

无论何时修改数组,都需要复制一份。如果修改现有数组,其他函数(例如迭代)可能无法按预期运行。

【讨论】:

    【解决方案2】:

    CopyOnWriteArrayList 在任何 mutator 方法中创建新的数组实例,以确保 Iterator 将始终使用底层数组数据的“快照”,这在 Iterator 创建时是实际的。 它可以防止 ConcurrentModificationException,但某些值可能会过时(例如已删除的元素)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      相关资源
      最近更新 更多