java - ArrayList(Collection<? extends E> c) 线程安全吗?

标签 java multithreading arraylist thread-safety

创建 ArrayList 的新实例是否线程安全?通过构造函数 ArrayList(Collection<? extends E> sourceCollection)没有任何额外的同步,假设 sourceCollection是同步的吗?更具体地说,在这种情况下,我们能否依靠新列表来准确包含当时集合中的元素 new ArrayList(sourceCollection)被调用?我们能否依靠新列表保持一致状态?

我问这个问题是因为我在书中看到了有关如何将对象限制为线程堆栈上的局部变量的并发示例。在这些示例中,一个方法被传递了一个对共享对象的引用,并且在该方法内部,该对象的一个​​副本存储在一个局部变量中——所有这些都没有任何同步。据称可以通过这种方式实现线程安全。一个一般的例子是:

public void someMethod(Collection<String> source) {
    List<String> localList = new ArrayList<>(source);
    ...
}

最佳答案

提示:正如@John Bollinger 刚刚提到的,特定的ArrayList 实现不在语言规范中。所以下面的写法适用于 Oracle java 8 实现。


是的,如果source是同步集合是安全的,因为这种情况下的ArrayList构造函数使用了source集合的toArray()方法,这也是同步的并产生新的数据副本:

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    // ...
}

关于java - ArrayList(Collection<? extends E> c) 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42236414/

相关文章:

java - 如何为 fragment 设置列表适配器

multithreading - Perl:特殊变量线程安全吗?

java - ArrayList 不通过套接字更新内容

java - 在java中比较一个大列表与另一个小列表的最佳方法?

java - 在 Java 中维护排序的 ArrayList 的最有效方法(速度方面)是什么?

java - Sun Solaris 服务器证书中的证书链验证程序错误被 ChainVerifier 拒绝

java - 方法定义中的 "throws ArithmeticException"只是装饰性的吗?

java - JPA实体字段中多维数组的正确注释是什么

java - BlockingQueue 对于所有线程来说始终都是一样的吗?

java - 如何启动新的JavaFX(应用程序)线程?