考虑以下使用Java 8流的不太正经的程序:
private int biggestInt;
private void run() {
ExecutorService executor = Executors.newWorkStealingPool();
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 0; i<50; i++) {
callables.add(randomInt());
}
try {
executor.invokeAll(callables)
.stream()
.map(future -> {
try {
return future.get();
} catch (Exception e) {
throw new IllegalStateException(e);
}
})
.forEach(this::compareBiggestInt);
} catch (InterruptedException e) { /* do nothing */ }
}
private Callable<Integer> randomInt() {
return () -> {
Random random = new Random(System.currentTimeMillis());
return random.nextInt();
};
}
private void compareBiggestInt(Integer in) {
if (in > biggestInt)
biggestInt = in;
}
我的问题是,forEach(this::compareBiggestInt)是否并行执行,从而会在biggestInt中引入竞争条件?
如果是这样,我该如何避免这种竞争条件?例如,我是否可以像下面这样更改方法?
private synchronized void compareBiggestInt(Integer in) {[...]}
任何帮助都是受到欢迎的!
Collector
类的描述中看到它。 - holi-javareduce
是Reduction,collect
是Mutable reduction。 - Holgerjava.util.stream
包的文档,其中描述了几个不同的概念。Reduction是其中之一,描述了该概念及其相关方法reduce
,Mutable reduction是另一个概念,在随后的部分中使用相关方法collect
进行描述。reduce
方法的文档清楚地链接到Reduction,但是,如果您向下滚动到下一个部分,您将进入Mutable reduction,但是如果您读取这两个部分,您应该注意到它是新的部分。 - HolgerBinaryOperator
中的maxBy
需要一个Comparator
,所以操作必须是.reduce(BinaryOperator.maxBy(Comparator.naturalOrder()))
,但你可以通过 Stream API 提供的.max(Comparator.naturalOrder())
简化此操作,它在内部实现上执行的也是相同的操作。 - Holger