我实际上试图回答这个问题如何跳过从 Files.lines 获得的 Stream<String> 的偶数行。所以我虽然这个收集器不能很好地并行工作:
private static Collector<String, ?, List<String>> oddLines() {
int[] counter = {1};
return Collector.of(ArrayList::new,
(l, line) -> {
if (counter[0] % 2 == 1) l.add(line);
counter[0]++;
},
(l1, l2) -> {
l1.addAll(l2);
return l1;
});
}
但它有效。
编辑:它实际上并没有工作;我被我的输入集太小而无法触发任何并行性这一事实愚弄了。见评论中的讨论。
我认为这行不通,因为我想到了以下两个处决计划。
1.counter
数组在所有线程之间共享。
线程 t1 读取 Stream 的第一个元素,所以满足 if 条件。它将第一个元素添加到其列表中。然后在他有时间更新数组值之前执行停止。
线程 t2,表示从流的第 4 个元素开始,将其添加到其列表中。所以我们最终得到了一个不需要的元素。
当然,既然这个收集器似乎可以工作,我想它不会那样工作。无论如何,更新都不是原子的。
2.每个Thread都有自己的数组副本
在这种情况下,更新没有更多问题,但没有什么能阻止我线程 t2 不会从流的第 4 个元素开始。所以他也不会那样工作。
所以看起来它根本不像那样工作,这让我想到了一个问题……收集器是如何并行使用的?
有人可以基本上解释一下它是如何工作的,以及为什么我的收集器在并行运行时会工作吗?
非常感谢!