ArrayList构造函数的线程安全性

我正在看这段代码。 这个构造函数委托给本地方法“System.arraycopy”

线程安全吗? 我的意思是它可以抛出一个ConcurrentModificationException?

public Collection<Object> getConnections(Collection<Object> someCollection) {
    return new ArrayList<Object>(someCollection);
}

如果要复制的集合是ThreadSafe,例如CopyOnWriteArrayList,它有什么区别吗?

public Collection<Object> getConnections(CopyOnWriteArrayList<Object> someCollection) {
    return new ArrayList<Object>(someCollection);
}

编辑:我知道ThreadSafe!= ConcurrentModificationException。 我试图在某个时间点对数据进行快照。 因此,如果另一个线程通过拷贝中途写入someCollection,我不在乎结果是否有新对象。 我只是不希望它抛出ConcurrentModificationException或更糟


你的问题是你是否可以安全地使用new ArrayList<Foo>(thatCollection)获取可能正在由另一个线程进行并发修改的集合的快照。 答案是:只要thatCollection本身是线程安全的,是的。 因此,如果它是CopyOnWriteArrayListsynchronizedListVector ,如果它不是线程安全的,例如,如果它是另一个ArrayList ,那么你不好。 (会发生什么情况可能比ConcurrentModificationException更糟糕。)

原因是ArrayList构造函数只对其他集合进行单个原子调用 - 对其toArray方法。 所以它基本上享有该方法本身具有的任何线程安全保证。 它并不总是这样实施,但现在正是因为这个原因。 我们用ImmutableList.copyOf在Guava中做同样的事情。


这个构造函数委托给本地方法“System.arraycopy”

实际上,它在someCollection上调用了someCollection toArray() 。 如果someCollection是一个ArrayList那最终会调用System.arraycopy 。 对于其他集合类型,数组将以其他方式创建。

线程安全吗?

没有。

我的意思是它可以抛出一个ConcurrentModificationException?

如果它是一个ArrayList它不会抛出ConcurrentModificationException ...但是这不会使它线程安全!

例如,如果一个不同的线程在您的线程调用此构造函数时在someCollection上调用set(obj, pos) ,那么新创建的ArrayList的内容是不可预知的。


线程安全和ConcurrentModificationException是不同的概念。 线程安全对象是多线程可以同时调用其方法的对象,并且保证对象中的数据不会受到损坏(例如:http://thejavacodemonkey.blogspot.com/2007/08/making-您的Java类线程safe.html)。 例如,当您正在迭代集合并且集合发生更改时,会发生ConcurrentModificationException。 更改可能来自不同的线程或同一个线程。

在构造函数中,如果另一个线程在构造函数复制时更改someCollection ,则可能导致未定义的行为(例如,新集合中的数据损坏,因为集合不是线程安全的)或ConcurrentModificationException(如果集合的确如此检测并发修改,但这并不能保证,因为它不是线程安全的...... :-)

如果您的构造函数要使用Collection<Object> ,则需要确保其他线程在构造函数返回之前不会修改该集合。

另一方面,CopyOnWriteArrayList是线程安全的并且保证不会抛出ConcurrentModificationException,因此您应该以这种方式安全地执行此操作,而无需编写额外的同步代码。

链接地址: http://www.djcxy.com/p/66515.html

上一篇: Thread safety of ArrayList constructors

下一篇: How does ConcurrentHashMap work internally?