An
ArrayList未同步。没有定义尝试同时向其添加元素。来自
forEach:
对于并行流管道,此操作不能保证尊重流的遇到顺序,因为这样做会牺牲并行性的好处。 对于任何给定的元素,可以在库选择的任何时间和线程中执行该操作 。
在第二个示例中,最终导致多个线程同时调用
add数组列表,并且
ArrayList文档显示:
请注意,此实现未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改列表,则必须在外部进行同步。
错误的解决方案
如果你改变了使用的
ArrayList一个
Vector,你会得到正确的结果,因为这个列表实现同步。它的Javadoc说:
与新的集合实现不同,它
Vector是同步的。
但是,请不要使用它!此外,由于显式同步,它最终可能会变慢。
正确的方法
明确地避免这种情况的是,Stream API
使用该方法提供了可变的简化范例
collect。下列
List<String> values = list.stream().map(i -> "foo").collect(Collectors.toList());
无论是否并行运行,都将始终提供正确的结果。Stream管道在内部处理并发,并确保在并行流的collect操作中使用非并发收集器是安全的。
Collectors.toList()是一个内置的收集器,它将一个Stream的元素累积到一个列表中。



