You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证Java多线程归并排序代码是否真正实现多线程?

多线程归并排序实现疑问解答

你的代码完全没有实现多线程,本质就是一种繁琐的普通函数调用,核心问题分析如下:

问题根源

  1. Multi类虽然继承了Thread,但既没有调用start()方法启动线程,且run()方法是空实现,完全没用到线程的异步执行逻辑。
  2. 你直接调用了Multi的doSort()方法,这个方法只是在当前线程里同步调用了merge.mergeSort(myItems),和直接写new Sort().mergeSort(...)没有任何区别,所有排序逻辑都是在同一个线程里顺序执行的。

你的原代码展示

Sort类代码

public class Sort {

    public int[] mergeSort(int[] myItems) {

        Splice splicer = new Splice();

        if (myItems.length < 2) {
            return myItems;
        }

        int mid = myItems.length / 2;

        //splits the load of each recursive call to different threads to run at the same time
        int[] left = new Multi(splicer.splice(myItems, 0, mid-1)).doSort();
        int[] right = new Multi(splicer.splice(myItems, mid, myItems.length -1)).doSort();
        
        ...
        return myItems;
   }
}

Multi线程类代码

public class Multi extends Thread {

    Sort merge = new Sort();
    private int[] myItems;

    public Multi(int[] myItems) {
        this.myItems = myItems;
    }

    public void run() {
    }

    public int[] doSort() {
        return merge.mergeSort(myItems);
    }

}

正确的多线程实现思路

要真正实现多线程归并排序,需要让左右数组的排序在不同线程中异步执行,并且等待线程完成后获取结果再归并。因为Thread的run()方法没有返回值,用Callable+FutureTask处理带返回值的线程任务会更合适:

修改后的Multi任务类

import java.util.concurrent.Callable;

public class Multi implements Callable<int[]> {
    private final Sort merge = new Sort();
    private final int[] myItems;

    public Multi(int[] myItems) {
        this.myItems = myItems;
    }

    @Override
    public int[] call() {
        // 在子线程中执行排序逻辑
        return merge.mergeSort(myItems);
    }
}

修改后的Sort类mergeSort方法

import java.util.concurrent.FutureTask;

public class Sort {

    public int[] mergeSort(int[] myItems) {
        Splice splicer = new Splice();
        if (myItems.length < 2) {
            return myItems;
        }

        int mid = myItems.length / 2;
        // 创建左右排序任务
        FutureTask<int[]> leftTask = new FutureTask<>(new Multi(splicer.splice(myItems, 0, mid - 1)));
        FutureTask<int[]> rightTask = new FutureTask<>(new Multi(splicer.splice(myItems, mid, myItems.length - 1)));

        // 启动两个线程异步执行
        new Thread(leftTask).start();
        new Thread(rightTask).start();

        try {
            // 等待两个线程完成,获取排序后的数组
            int[] left = leftTask.get();
            int[] right = rightTask.get();
            // 执行归并逻辑
            int[] merged = new int[left.length + right.length];
            int i = 0, j = 0, k = 0;
            while (i < left.length && j < right.length) {
                merged[k++] = left[i] <= right[j] ? left[i++] : right[j++];
            }
            while (i < left.length) merged[k++] = left[i++];
            while (j < right.length) merged[k++] = right[j++];
            return merged;
        } catch (Exception e) {
            e.printStackTrace();
            return myItems;
        }
    }
}

额外优化提示

不要在所有递归层级都创建线程,线程创建和调度有开销。可以设置一个阈值(比如数组长度小于1000时),直接用普通归并排序,避免不必要的线程开销。

内容的提问来源于stack exchange,提问作者eilou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:32:44