考虑以下类,它表示父子单向层次结构中的单个节点:
public class Component {
private final int value;
private final List<Component> children;
public Component(int value) {
this.value = value;
this.children = new ArrayList<>();
System.out.println("Created: " + this);
}
public Component child(Component child) {
this.children.add(child);
return this;
}
public Stream<Component> asFlatStream() {
return Stream.concat(Stream.of(this),
children.stream().flatMap(Component::asFlatStream));
}
public List<Component> asFlatList() {
List<Component> flat = new ArrayList<>();
return asFlatListInternal(flat);
}
public List<Component> asFlatListInternal(List<Component> flat) {
flat.add(this);
for (Component child : children) {
child.asFlatListInternal(flat);
}
return flat;
}
@Override
public String toString() {
return String.valueOf(value);
}
public static void main(String[] args) {
Component root = new Component(0)
.child(new Component(1)
.child(new Component(5))
.child(new Component(6))
.child(new Component(7)
.child(new Component(8))))
.child(new Component(2)
.child(new Component(9))
.child(new Component(10)))
.child(new Component(3))
.child(new Component(4));
Supplier<Stream<Component>> streamSupplier = () -> root.asFlatStream();
System.out.print("Sequential as stream: ");
streamSupplier.get()
.peek(c -> System.out.print(c + " "))
.forEach(c -> { });
System.out.print("\n Parallel as stream: ");
streamSupplier.get().parallel()
.peek(c -> System.out.print(c + " "))
.forEach(c -> { });
System.out.print("\n Sequential as list: ");
root.asFlatList().stream()
.peek(c -> System.out.print(c + " "))
.forEach(c -> { });
System.out.print("\n Parallel as list: ");
root.asFlatList().stream().parallel()
.peek(c -> System.out.print(c + " "))
.forEach(c -> { });
}
}
单运行的可能输出:
Created: 0
Created: 1
Created: 5
Created: 6
Created: 7
Created: 8
Created: 2
Created: 9
Created: 10
Created: 3
Created: 4
Sequential as stream: 0 1 5 6 7 8 2 9 10 3 4
Parallel as stream: 1 5 6 7 8 2 0 9 10 3 4
Sequential as list: 0 1 5 6 7 8 2 9 10 3 4
Parallel as list: 2 9 8 10 1 0 7 6 4 3 5
对几个连续运行的观察:
为简洁起见,我使用的示例进行了简化,我在具有数百个组件和实际处理逻辑的实际应用程序中观察到相同的行为(每个块都是非空的)。
在真实的应用程序中,我给偷看时间戳并为平均持续1-2秒的每个块实现了一个但仍然没有重叠,但他们总是等待前一个完成建议没有发生实际的并行处理。我还尝试了各种线程池大小,它是我拥有的核心数量的2到2倍,但没有任何效果。
将实际应用程序的运行时间减少到1/3的唯一解决方案让我对实际使用并行性的信心是从基于流的扁平化算法切换到基于列表的算法。
我对(4)的期望是否错误,如果没有,对行为的解释是什么?或者基于流的展平算法是否被破坏,如果是,那么它的修复是什么?