【问题标题】:Java 8 stream from modified collection来自修改集合的 Java 8 流
【发布时间】:2015-05-18 10:27:28
【问题描述】:

假设我有一个 List 的对象,这些对象仅由一个线程修改(线程可以添加或删除对象),而另一个线程偶尔使用上述集合中的流 api 对其进行一些流操作,并在end(急切操作)返回一个新集合。 这是一个线程安全的场景吗?毕竟只有一个线程更新集合。

【问题讨论】:

  • 我不这么认为...如果一个线程删除一个项目而另一个线程试图读取它会发生什么?不过我可能是错的,因为我不确定流在底层是如何工作的。
  • 这不是一个线程安全的场景,因为你有一个线程写入和一个或多个线程读取。为了使其线程安全,您需要确保写入不会干扰读取。

标签: java multithreading java-8 java-stream


【解决方案1】:

这完全取决于您的源 List 实现。使用ArrayList,您可能得到ConcurrentModificationException(或者可能会收到损坏的数据或其他一些异常:请参阅评论)。使用CopyOnWriteArrayList,您可以安全地使用流操作:他们将看到创建流时实际的列表状态。在任何情况下,您都应该查看相应集合的 spliterator() 方法的文档,看看在并发环境中使用它是否安全。

【讨论】:

  • 您可能得到ConcurrentModificationException,因为它将在尽力而为的基础上被抛出。您可能会默默地获取损坏的数据。或者一个不同的异常,它不会告诉你它是由并发操作引起的,例如一个IndexOutOfBoundsException。在虚假问题突然开始出现之前,您可能可以长时间摆脱损坏的代码......
【解决方案2】:

你应该得到并发修改异常,因为你正在使用这个集合同时读取和写入。

【讨论】:

  • 如果集合允许并发修改怎么办?
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 2015-06-29
  • 2015-10-20
  • 2021-01-08
  • 1970-01-01
相关资源
最近更新 更多