web-dev-qa-db-ja.com

リクエストアイテムごとに複数のスレッドを作成する方法

注文レベルでマルチスレッドを使用して以下のコードを処理しようとしています。

_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の順序は気になりませんが、rulesの順序は気になりません。オーダーは任意の順序で処理できますが、ルールは各オーダーで同じ順序で実行する必要があります。

助けてください。

9
mayank bisht

使用できます:

orders.stream().parallel().forEachOrdered(// Your rules logic goes here. )

ForEachOrderedは、ストリームの順序を維持することを保証します。

参考までに:

orders.stream().parallel().forEachOrdered( order -> {

            rules.stream().parallel().forEachOrdered ( rule -> {

                 System.out.println( " Order : " + order + " rule :" + rule);
            });

        });

注:これを行うことはできますが、並列性と秩序はあまりうまく融合しないため、パフォーマンスを注意深く監視する必要があります。

出力

 Order : order1 rule :rule1
 Order : order1 rule :rule2
 Order : order1 rule :rule3
 Order : order2 rule :rule1
 Order : order2 rule :rule2
 Order : order2 rule :rule3
 Order : order3 rule :rule1
 Order : order3 rule :rule2
 Order : order3 rule :rule3
 Order : order4 rule :rule1
 Order : order4 rule :rule2
 Order : order4 rule :rule3
 Order : order1 rule :rule1
 Order : order1 rule :rule2
 Order : order1 rule :rule3
4
Pramod S. Nikam

異なるスレッドからfinalListに同時に要素を追加します。これにより、さまざまな注文にルールを適用した結果が混在します(ルールは注文によってグループ化されていません)。

orderごとに一時リストを作成し、finalList内のすべての一時リストを同期的にマージすることで修正できます。

ここでは、Stream-API(Java 9+)を使用してそれを行う方法を示します。

_List<AppliedRule> finalList = orders.parallelStream().map(order ->
        rules.stream().map(rule -> applyRule(order, rule)).collect(Collectors.toList())
).collect(Collectors.flatMapping(Collection::stream, Collectors.toList()));
_

注:ストリームの収集中にフラットマッピングを同期的に実行するために、ここでは単純なflatMapの代わりにCollectors.flatMapping()を使用しています。


Java 8アナログ:

_List<AppliedRule> finalList = orders.parallelStream().map(order ->
        rules.stream().map(rule -> applyRule(order, rule)).collect(Collectors.toList())
).collect(Collectors.toList())
        .stream()
        .flatMap(Collection::stream)
        .collect(Collectors.toList());
_
1
Bananon

これは機能しますか?

final int rulesSize = rules.size();
AtomicInteger atomicInteger = new AtomicInteger(0);
orders.stream().parallel().forEach(order -> {
    IntStream.range(0, rulesSize).parallel().forEach( i -> {
        synchronized (atomicInteger) {
            System.out.println(" Order : " + order + " rule :" + rules.get(atomicInteger.getAndIncrement() % rulesSize));
        }
    });
});

出力

 Order : order1 rule :rule1
 Order : order4 rule :rule2
 Order : order1 rule :rule3
 Order : order3 rule :rule1
 Order : order3 rule :rule2
 Order : order3 rule :rule3
 Order : order2 rule :rule1
 Order : order2 rule :rule2
 Order : order2 rule :rule3
 Order : order1 rule :rule1
 Order : order1 rule :rule2
 Order : order4 rule :rule3
 Order : order1 rule :rule1
 Order : order4 rule :rule2
 Order : order1 rule :rule3
0
BHAWANI SINGH

サードパーティのライブラリを試してもかまわない場合。これが私のライブラリのサンプルです: abacus-util

StreamEx.of(orders).parallelStream().forEach(order -> {}}

また、スレッド番号を指定することもできます。

StreamEx.of(orders).parallelStream(maxThreadNum).forEach(order -> {}}

ruleの順序は保持されます。

ちなみに、並列ストリームなので、コード...finalList.add(...おそらく動作しません。リストに結果を集めた方が良いと思います:

StreamEx.of(orders).parallelStream().map/flatMap(order -> {...}}.toList()

後でなんらかの理由でorderの順序を保持したい場合でも実行できます。

StreamEx.of(orders).indexed().parallelStream()
      .map/flatMap(order -> {...}}.sortedBy(...index).toList()
0
user_3380739