gpt4 book ai didi

java - 我是否需要一个并发集合来通过多个线程将元素添加到列表中?

转载 作者:搜寻专家 更新时间:2023-11-01 02:09:02 29 4
gpt4 key购买 nike

static final Collection<String> FILES = new ArrayList<String>(1);    

for (final String s : list) {
new Thread(new Runnable() {
public void run() {
List<String> file2List = getFileAsList(s);
FILES.addAll(file2List);
}
}).start();
}

这个集合变得非常大,但代码运行完美。我以为我会得到并发修改异常,因为 FILES 列表必须扩展其大小,但它从未发生过。

这段代码是 100% 线程安全的吗?

代码需要 12 秒才能加载,几个线程同时添加元素。

我尝试先创建线程然后运行它们,但我得到了相同的结果(时间和正确性)

最佳答案

不,代码不是线程安全的。它可能会或可能不会抛出 ConcurrentModificationException,但您最终可能会丢失元素或添加两次元素。将列表更改为

Collection<String> FILES = Collections.synchronizedList(new ArrayList<String>());

可能已经是一个解决方案,假设最耗时的部分是 getFilesAsList 方法(并且将结果元素添加到 FILES列表)。

顺便说一句:当getFileAsList 正在访问硬盘驱动器时,您应该执行详细的性能测试。多线程硬盘驱动器访问可能比单线程访问,因为硬盘驱动器磁头可能不得不在驱动器周围跳来跳去,无法读取连续 block 中的数据。 p>


编辑:回应评论:该程序“很可能”不时产生ArrayIndexOutOfBoundsExceptions:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class ConcurrentListTest
{
public static void main(String[] args) throws InterruptedException
{
for (int i=0; i<1000; i++)
{
runTest();
}
}

private static void runTest() throws InterruptedException
{
final Collection<String> FILES = new ArrayList<String>(1);
// With this, it will always work:
// final Collection<String> FILES = Collections.synchronizedList(new ArrayList<String>(1));

List<String> list = Arrays.asList("A", "B", "C", "D");
List<Thread> threads = new ArrayList<Thread>();
for (final String s : list)
{
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
List<String> file2List = getFileAsList(s);
FILES.addAll(file2List);
}
});
threads.add(thread);
thread.start();
}
for (Thread thread : threads)
{
thread.join();
}
System.out.println(FILES.size());
}

private static List<String> getFileAsList(String s)
{
List<String> list = Collections.nCopies(10000, s);
return list;
}

}

当然,不能严格保证它会。如果它没有为你创造这样的异常(exception),你应该考虑玩彩票,因为你一定非常幸运。

关于java - 我是否需要一个并发集合来通过多个线程将元素添加到列表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22528306/

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