1. 概述

Arrays.sort() 是我们日常开发中再熟悉不过的工具,用于对对象或基本类型数组进行排序。JDK 8 引入了一个新方法 —— Arrays.parallelSort(),旨在利用多核优势提升排序性能。

本文将深入对比 sort()parallelSort() 的行为差异、底层机制及适用场景,帮你避免踩坑,做出更合理的技术选型。


2. Arrays.sort()

Arrays.sort() 用于对数组进行排序,底层采用的是 Dual-Pivot Quicksort(双轴快排) 算法 —— 这是 Java 团队对经典快排的优化实现,性能优于传统单轴快排。

关键特性:

  • 单线程执行,不启用并发
  • 提供两个重载方法:
    • sort(array):对整个数组排序
    • sort(array, fromIndex, toIndex):仅对指定范围 [fromIndex, toIndex) 排序

示例代码

@Test
public void givenArrayOfIntegers_whenUsingArraysSortMethod_thenSortFullArrayInAscendingOrder() {
    int[] array = { 10, 4, 6, 2, 1, 9, 7, 8, 3, 5 };
    int[] expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    Arrays.sort(array);

    assertArrayEquals(expected, array);
}

@Test
public void givenArrayOfIntegers_whenUsingArraysSortWithRange_thenSortRangeOfArrayAsc() {
    int[] array = { 10, 4, 6, 2, 1, 9, 7, 8, 3, 5 };
    int[] expected = { 10, 4, 1, 2, 6, 7, 8, 9, 3, 5 };

    Arrays.sort(array, 2, 8);

    assertArrayEquals(expected, array);
}

优缺点总结

✅ 优点 ❌ 缺点
小数据集下性能优异 大数据集性能下降明显
实现简单,开销低 无法利用多核 CPU 并行能力

⚠️ 注意:sort() 是纯同步操作,不会创建额外线程,适合大多数常规场景。


3. Arrays.parallelSort()

Arrays.parallelSort() 同样用于数组排序,API 设计与 sort() 完全一致,也支持全数组和区间排序。

示例代码

@Test
public void givenArrayOfIntegers_whenUsingArraysParallelSortMethod_thenSortFullArrayInAscendingOrder() {
    int[] array = { 10, 4, 6, 2, 1, 9, 7, 8, 3, 5 };
    int[] expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    Arrays.parallelSort(array);

    assertArrayEquals(expected, array);
}

@Test
public void givenArrayOfIntegers_whenUsingArraysParallelSortWithRange_thenSortRangeOfArrayAsc() {
    int[] array = { 10, 4, 6, 2, 1, 9, 7, 8, 3, 5 };
    int[] expected = { 10, 4, 1, 2, 6, 7, 8, 9, 3, 5 };

    Arrays.parallelSort(array, 2, 8);

    assertArrayEquals(expected, array);
}

底层原理

parallelSort() 采用的是 并行归并排序(parallel sort-merge)算法,核心流程如下:

  1. 将数组拆分为多个子任务
  2. 使用 ForkJoinPool 并行处理每个子任务的排序
  3. 最终将有序子数组合并成完整有序数组

⚠️ 但并行不是无条件启用的!JVM 有明确阈值控制:

  • 若数组长度 ≤ 8192
  • 或 CPU 只有单核

👉 则退化为 单线程的 Dual-Pivot Quicksort,避免并发开销反噬性能。

优缺点总结

✅ 优点 ❌ 缺点
大数据集下显著提升性能 小数组反而更慢(线程调度开销)
充分利用多核 CPU 资源 内存占用略高(归并需要辅助空间)

💡 简单粗暴地说:数据越大,并行收益越高;数据越小,越容易翻车。


4. 性能对比

以下数据基于 JMH 基准测试(Benchmark),环境为:

  • CPU:AMD A10 PRO 2.1GHz 四核
  • JDK:1.8.0_221
数组大小 Arrays.sort() (ms) Arrays.parallelSort() (ms)
1,000 0.048 0.054
10,000 0.847 0.425
100,000 7.570 4.395
1,000,000 65.301 37.998

关键结论:

  • 小数据(< 1万)sort() 更快,parallelSort() 因线程开销反而拖慢
  • 中大型数据(≥ 10万)parallelSort() 性能优势明显,提速接近 40%~45%
  • ⚠️ 并行收益取决于 CPU 核心数和数据规模,不是“用了就快”

5. 总结与建议

场景 推荐方法 理由
数组长度 < 10,000 Arrays.sort() 避免并发开销,性能更稳
数组长度 ≥ 100,000 Arrays.parallelSort() 多核并行优势显著
不确定数据规模 优先 sort(),压测验证 实际性能受硬件影响大,别想当然

最佳实践建议:

  • 日常开发中,小数组一律用 sort()
  • 大数据批处理、排序密集型任务,考虑 parallelSort()
  • 生产环境使用前务必做 JMH 压测,结合实际 CPU 和数据分布评估

所有示例代码已托管至 GitHub:https://github.com/johnchen/tutorials/tree/master/core-java-modules/core-java-arrays-sorting


原始标题:Arrays.sort vs Arrays.parallelSort

« 上一篇: Java 中的分支预测