我试图在订单级别使用多线程处理下面的代码。
List<String> orders = Arrays.asList("order1", "order2",
"order3", "order4", "order1");
- 当前顺序执行:**
orders.stream().forEach(order -> {
rules.forEach(rule -> {
finalList.add(beanMapper.getBean(rule)
.applyRule(createTemplate.apply(getMetaData.apply(rule), command),
order));
});
});
我曾尝试使用:
orders.parallelStream().forEach(order -> {}} // code snippet.
但是它正在更改**rules. forEach(rule-〉{}}**的顺序。
例如:
输入:
List<String> orders = Arrays.asList("order1", "order2",
"order3", "order4", "order1");
List<String> rules = Arrays.asList("rule1", "rule2", "rule3");
预期产出:
order1 with rule1, rule2, rule3
order2 with rule1, rule2, rule3
parallelStream()
的实际输出:
order1 with rule3, rule1, rule2
order1 with rule2, rule1, rule3
我不关心orders的顺序,但关心ehrules的顺序。订单可以按任何顺序处理,但规则应按相同顺序执行每个订单。
请帮帮我。
5条答案
按热度按时间7lrncoxx1#
您可以用途:
ForEachOrdered保证维护流的顺序。
因此,供您参考:
**注:**虽然我们可以做到这一点,但应密切关注性能,因为平行性和秩序并不完美结合!
产出
bzzcjhmw2#
您同时从不同的线程向
finalList
添加元素,这会导致将规则应用于不同顺序的混合结果(规则没有按顺序分组)。您可以通过为每个
order
创建一个临时列表,然后同步合并finalList
中的所有临时列表来解决这个问题。以下是使用Stream-API(Java 9+)实现此操作的方法:
注意:这里使用
Collectors.flatMapping()
而不是简单的flatMap
,以便在流收集期间同步运行平面Map。Java 8模拟版本:
uinbv5nw3#
这样行吗?
uklbhaso4#
订单的顺序可以是任何顺序,但规则的顺序不应该改变。同样,对于特定的顺序,规则应该成组出现。
如果是这样,就没有实际并行的余地。
何时
以及
是2个订单和2个规则的唯一有效运行,
以及
被认为是无效的,这不是并行性,只是
order
的随机化,可能没有任何好处。如果你对order1
总是排在第一感到"厌烦",你可以打乱列表,但仅此而已:甚至不需要流,只需要两个嵌套循环。测试:https://ideone.com/qI3dqd
但是它正在改变规则。forEach(rule-〉{}}的顺序。
不,它不会。
order
可以重叠,但每个顺序的rule
的顺序都保持不变。非并行forEach
为什么要做其他事情呢?示例代码:
测试:https://ideone.com/95Cybg
输出示例:
order
的顺序是混合的,但rule
总是1 - 2 - 3。我认为您的输出只是隐藏了配对(实际上您没有显示它是如何生成的)。当然,它可以被扩展一些延迟,所以
order
s的处理实际上会重叠:测试:https://ideone.com/cSFaqS
输出示例:
这可能是你已经看到的东西,只是没有
orderx
部分。随着order
的可见,可以跟踪到rule
不断出现1 - 2 - 3,* 每个order
*。而且,你的示例列表包含order1
两次,这肯定无助于看到发生了什么。kcwpcxri5#
如果你不介意尝试第三方库。这里是我的库的样本:abacus-common
您甚至可以指定线程数:
将保留
rule
的顺序。顺便说一下,由于它是并行流,所以
...finalList.add(...
代码很可能无法工作,我认为最好收集结果以列出:即使你以后出于某种原因想保持
order
的顺序,这也是可行的: