gpt4 book ai didi

java - 为什么使用 CopyOnWriteArrayList 时结果很奇怪?

转载 作者:太空宇宙 更新时间:2023-11-04 07:06:30 26 4
gpt4 key购买 nike

当我在 CopyOnWriteArrayList 中使用多线程时,输出结果有时不是目标。代码是:

public class CopyOnWriteArrayListTest {

public static void main(String[] args) throws InterruptedException {
while(true){

CopyOnWriteArrayList<String> ll = new CopyOnWriteArrayList<String>(new String[10]);

CountDownLatch latch = new CountDownLatch(2);
ThreadDemo t1 = new ThreadDemo(0, ll, latch);
ThreadDemo t2 = new ThreadDemo(1, ll, latch);

t1.start();
t2.start();

latch.await();
System.out.println(ll);
}
}
}

public class ThreadDemo extends Thread implements Runnable {
private int code;
private List<String> list;
private CountDownLatch latch;
public ThreadDemo(int i, List<String> l, CountDownLatch latch){
code = i;
list = l;
this.latch = latch;
}

@Override
public void run() {
writeList(list);
}

private synchronized void writeList(List<String> l){
l.add(code, String.valueOf(code));
latch.countDown();
}

}

输出为 [0, 1, null, null, null, null, null, null, null, null, null, null] 或[0、空、1、空、空、空、空、空、空、空、空、空]。它应该始终为 [0, 1, null, null, null, null, null, null, null, null, null, null]。

我看了CopyOnWriteArrayList的源代码,没有找到奇怪结果的答案。

请帮我解决一下,谢谢!

最佳答案

当添加一个元素时,你实际上是在移动列表,而不是在该索引处替换,因此当在 0 处添加元素时,位置 1 处的元素变为位置 2。因此,每当插入到位置 1 的操作发生在 0 之前时,就会出现第二个元素为 null 的情况。即:

CopyOnWriteArrayList<String> ll = new CopyOnWriteArrayList<String>(new String[10]);
ll.add(1, "1");
ll.add(0, "0");
System.out.println(ll);

>>> [0, null, 1, null, null, null, null, null, null, null, null, null]

这种情况不会一直发生,因为通常从您启动首先插入 0 的线程开始。如果你翻转生成线程的顺序,你几乎会不断地看到它。

我认为您正在寻找的是“set”方法

list.set(code, String.valueOf(code));

更改它会给出您期望的输出。另外值得一提的是,COWList 是线程安全的,因此 writeList 上的同步不是必需的。

关于java - 为什么使用 CopyOnWriteArrayList 时结果很奇怪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21298001/

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