gpt4 book ai didi

java - 为什么ArrayList流不报告CONCURRENT特征?

转载 作者:行者123 更新时间:2023-12-01 19:39:07 25 4
gpt4 key购买 nike

在阅读 java 流的文档时,我了解到:

(new ArrayList<String>().stream().spliterator().characteristics() & Spliterator.CONCURRENT) != 0

应评估为 true。然而,在测试时,却没有。

我错过了什么。

我引用的java文档: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

Non-interference

Streams enable you to execute possibly-parallel aggregate operations over a variety of data sources, including even non-thread-safe collections such as ArrayList. This is possible only if we can prevent interference with the data source during the execution of a stream pipeline. Except for the escape-hatch operations iterator() and spliterator(), execution begins when the terminal operation is invoked, and ends when the terminal operation completes. For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification. Concurrent stream sources are those whose Spliterator reports the CONCURRENT characteristic. Accordingly, behavioral parameters in stream pipelines whose source might not be concurrent should never modify the stream's data source. A behavioral parameter is said to interfere with a non-concurrent data source if it modifies, or causes to be modified, the stream's data source. The need for non-interference applies to all pipelines, not just parallel ones. Unless the stream source is concurrent, modifying a stream's data source during execution of a stream pipeline can cause exceptions, incorrect answers, or nonconformant behavior. For well-behaved stream sources, the source can be modified before the terminal operation commences and those modifications will be reflected in the covered elements. For example, consider the following code:

 List<String> l = new ArrayList(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = sl.collect(joining(" "));

First a list is created consisting of two strings: "one"; and "two". Then a stream is created from that list. Next the list is modified by adding a third string: "three". Finally the elements of the stream are collected and joined together. Since the list was modified before the terminal collect operation commenced the result will be a string of "one two three". All the streams returned from JDK collections, and most other JDK classes, are well-behaved in this manner; for streams generated by other libraries, see Low-level stream construction for requirements for building well-behaved streams.

我也尝试过使用 CopyOnWriteArrayList。那里的 CONCURRENT 标志也没有设置。例如,对于 ConcurrentLinkedQueue,设置了 CONCURRENT 标志。

版本

我正在使用 Oracle javaSe-11 和 jdk-11.0.2。

最佳答案

CONCURRENT characteristic定义为:

Characteristic value signifying that the element source may be safely concurrently modified (allowing additions, replacements, and/or removals) by multiple threads without external synchronization.

documentation of ArrayList说:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, …

再清楚不过了,ArrayList 作为 Stream 源除了 CONCURRENT 之外就是一切。

您引用的文档与此并不矛盾。但我不得不承认,如果在“对于行为良好的流源,……”之前有一个段落休息,让读者休息一下并反射(reflect)之前所说的内容,那么效果会更好,因为接下来的内容是不同的一点,适用于 ArrayList 以及所有其他“行为良好的流源”,但与 CONCURRENT 特征不再相关,并且不会影响之前描述的行为参数的约束。

所有新的观点是,您可以在 Stream 的终端操作开始之前更改 ArrayList ,但仍然仅从一个线程(或与您一起)自己的同步),但您仍然不允许在正在进行的终端操作期间执行结构修改,这排除了行为参数的任何结构修改,因为这些总是在正在进行的终端操作期间进行评估。

CopyOnWriteArrayList 的情况有所不同,它不会具有 CONCURRENT 特征,因为它的 spliterators 将具有 IMMUTABLE 特征,因为您将迭代不可变的快照;对原始 CopyOnWriteArrayList 的修改不会影响 Stream。

关于java - 为什么ArrayList流不报告CONCURRENT特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56001891/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com