Java 多线程向列表中添加字符串时出现问题

Java 多线程向列表中添加字符串时出现问题,java,multithreading,collections,thread-safety,Java,Multithreading,Collections,Thread Safety,这是一篇后续文章 那里的每个人都把注意力集中在列表的扩展上。我知道这是个问题,但是。。添加元素怎么样?那个线安全吗 示例代码 static final Collection<String> FILES = new ArrayList<String>(1000000); 那个线安全吗?这样做可能会有什么问题?ArrayList本身不同步。改用Collections.synchronizedList(new ArrayList())。使用Collections.syncro

这是一篇后续文章

那里的每个人都把注意力集中在列表的扩展上。我知道这是个问题,但是。。添加元素怎么样?那个线安全吗

示例代码

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

那个线安全吗?这样做可能会有什么问题?

ArrayList
本身不同步。改用
Collections.synchronizedList(new ArrayList())

使用
Collections.syncronizedList(new ArrayList(1000000))
即使列表没有展开,它也会保持其内部状态,例如当前大小。从更广泛的意义上讲,
ArrayList
被指定为一个可变对象,它不是线程安全的,因此对它同时调用任何mutator方法都是非法的

public boolean add(E e) {
     ensureCapacityInternal(size + 1);  // Increments modCount!!
     elementData[size++] = e;
     return true;
}
这是7u40-b43中ArrayList的源代码。 方法ensureCapacityInternal()不是线程安全的,size++也不是。
大小++由三个步骤完成,1)获取大小,2)大小+1,3)写回新值。

否。ArrayList不是线程安全的。使用Collections.synchronizedList(新的ArrayList())。我在我的帖子里解释过。你还不明白什么?在执行添加操作时,您可以得到不同的结果。再次阅读我的文章,你是参考,并试图问我更准确地你不理解的解释和什么是遗漏。我认为我对你的第一个问题的正确答案。所以你可以简单地删除这个问题。我在第一个列表中做了一些更新,这样可以更精确地解释它。这将同步整个列表(包括读取操作)。对于必须高效的代码,不建议使用。我建议显式使用。如果随机访问不是一个要求,我会选择or。我为什么要这样做?这就是我在问题中提出的问题
public boolean add(E e) {
     ensureCapacityInternal(size + 1);  // Increments modCount!!
     elementData[size++] = e;
     return true;
}