如何验证Java多线程归并排序代码是否真正实现多线程?
多线程归并排序实现疑问解答
你的代码完全没有实现多线程,本质就是一种繁琐的普通函数调用,核心问题分析如下:
问题根源
Multi类虽然继承了Thread,但既没有调用start()方法启动线程,且run()方法是空实现,完全没用到线程的异步执行逻辑。- 你直接调用了
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
相关产品推荐
相关产品推荐

