Java8のSteam APIで並行リダクション(concurrent reduction)をサポートした自作Collectorを作るとき、Collectorのcombiner関数呼ばれることはないと仮定しても良いものでしょうか?

(実効的な意味はない)下記サンプルコードでは、自作CollectorはCONCURRENTかつUNORDERED特性を持っており:

  • 並列ストリーム(parallel()あり)なら並列リダクション = supplier関数があるスレッド上で1回呼ばれる+各Workerスレッドから並行にaccumulator関数が呼ばれる
  • 逐次ストリーム(parallel()なし)なら単一スレッド上のリダクション = supplier関数+accumulator関数が単一スレッドから呼ばれる

と期待されるため、いずれのケースでもcombiner関数が使われる事は無いと考えられます。

import java.util.stream.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

public class DoesConcReductionCollectorNeedsCombiner {
  static public void main(String[] args) {
    ConcurrentMap<Integer, AtomicInteger> result =
      IntStream.range(1, 10_000_001).boxed()  // Stream<Integer>
        .parallel()  // 並列ストリーム化
        .collect(Collector.of(
          () -> new ConcurrentHashMap<>(),
          (m,v) -> {
            AtomicInteger a = m.putIfAbsent(v % 10, new AtomicInteger(v));
            if (a != null)
              a.getAndAdd(v);
          },
          (m,n) -> {
            // 並行リダクションなら呼び出されない? = 実装不要?
            // (まじめに実装するなら2つの並行Mapのマージが必要)
            System.out.println("!");
            return null;
          },
          Collector.Characteristics.CONCURRENT,
          Collector.Characteristics.UNORDERED
        ));
    System.out.println("r="+result);
  }
}