【发布时间】:2019-08-13 22:04:42
【问题描述】:
假设我有一个书籍元素列表:List<Book> libraryBooks 和以下代码:
List<BookAuthor> authors = new ArrayList<>();
libraryBooks.stream().forEach(e -> {
authors.add(createAuthor(e));
});
我环顾四周,发现了类似的问题,(如here)但我还不相信。因为我一直在阅读有关该主题的书,并且该书似乎表明,如果流并行运行,上述内容可能会引入竞争条件-但我没有使用并行流,因此上述内容也会受到竞争条件的影响?还是这本书有误/误导?
【问题讨论】:
-
“如果流并行运行,上述可能会引入竞争条件” - 它不一定是并行流,因为它不是线程安全的。当您在
forEach中添加元素时,任何其他线程都可能尝试修改authors。 -
我相信您的书展示了正确、惯用的方式来做您想做的事。为什么不使用这种惯用方式?
-
我发布的上述示例实际上是一个非常简单的示例,但我正在查看现有应用程序中的一些代码,它实际上做了更复杂的事情(即,使用构建器创建对象)然后将该新对象添加到列表中,但与我发布的上述示例相同。我只是想知道这是否会导致比赛条件?
-
@Nena 使用流的良好做法是编写可并行化的代码。一般来说,一个人应该能够用
parallelStream()替换stream()并且仍然有正确的代码。那里的情况并非如此,因为 ArrayList 不是线程安全的,并且会从并发线程进行修改。这就是本书所说的:你应该编写parallel-ready代码。如果它是顺序的,则它没有任何竞争条件,因为没有竞争。但它不是并行就绪的,因为如果它是并行的,它将有一个竞争条件。
标签: java lambda foreach race-condition