Spliterator 的核心是为 Stream API 提供可拆分、可估算、可描述的遍历契约;通过 trySplit() 逻辑分片、estimateSize() 辅助调度、characteristics() 声明语义、tryAdvance() 原子遍历,使 parallelStream() 能安全高效并发执行。

Spliterator 支持并行遍历和流式操作,核心不在于“它自己启动多线程”,而在于为 Stream API 提供可拆分、可估算、可描述的数据遍历契约。它让数据源能主动告诉流框架:“我支持怎么分、大概有多少、有什么特性”,从而让 parallelStream() 能安全高效地调度并发任务。
靠 trySplit() 实现逻辑分片,而非线程管理
trySplit() 是并行能力的起点:它不创建线程,也不触发执行,只是把当前遍历范围“切一刀”,返回一个新 Spliterator 覆盖前半段(或后半段),原实例负责剩下部分。这种分割是递归、惰性的——只有在并行流真正需要更多任务时才调用,且每次分割都必须保证:
- 两个 Spliterator 覆盖的元素区间互斥、无重叠
- 所有元素被且仅被一个 Spliterator 覆盖(不遗漏、不重复)
- 分割后原实例状态已推进(如数组索引更新),避免重复切分同一段
用 estimateSize() 和 characteristics() 辅助调度与优化
estimateSize() 不要求精确,但需合理反映剩余元素量级(例如数组用 end - current)。流框架据此判断是否值得继续 split —— 若预估只剩 2 个元素,通常不再拆分;若预估上百万,就可能多级切分。characteristics() 则声明关键语义,比如:
-
Spliterator.SIZED:大小固定,便于均分负载 -
Spliterator.ORDERED:元素有顺序,影响 reduce/fold 的合并方式 -
Spliterator.IMMUTABLE:源不可变,无需加锁
这些信息让 Stream 在并行阶段自动选择更优策略,比如跳过同步、启用组合式归约。
立即学习“Java免费学习笔记(深入)”;
通过 tryAdvance() 保障单线程安全遍历单元
不同于 Iterator 的 hasNext()+next() 两步分离,tryAdvance() 原子化完成“检查+消费+推进”三件事,彻底规避竞态条件。每个子 Spliterator 在各自线程中独立调用 tryAdvance(),无需额外同步。forEachRemaining() 则是它的批量优化版本,在确定无需中断时直接遍历到底,减少方法调用开销。
它不直接暴露给业务代码,而是由 StreamSupport 统一驱动
你几乎不会手动 new Spliterator 或调用 trySplit() 启动并行。真实流程是:
- 调用
list.parallelStream()→ 底层调用list.spliterator() - StreamSupport 创建并行流,根据 Spliterator 的 estimateSize() 和 characteristics() 决定初始分割粒度
- 工作线程从 ForkJoinPool 获取任务,每个任务持有一个 Spliterator,反复 trySplit() + tryAdvance() 直到无法再分
- 结果按特性(如 ORDERED)自动合并
自定义 Spliterator 时,重点不是写多线程逻辑,而是正确实现那四个抽象方法,让框架能信任你的分割语义。


















