我有合并排序http://pastebin.com/2uMGjTxr
的单线程版本它创建一个数组,用随机数填充它,并在其上调用执行合并排序的sort方法:
private static int[] sort(int[] array) {
//TODO: use multiple threads to speed up the sorting
return mergeSort(array, 0, array.length);
}
现在我想在java中使用多线程技术来提高性能。代码来自我的导师,他说我必须在sort方法中添加一些东西但实际上让我感到困惑。
合并排序是一种分而治之的算法:
所以我实际上会为每个子列表启动一个线程。你怎么看?如何根据给定实现并行化合并排序?有谁知道为什么我应该编辑排序方法?
答案 0 :(得分:4)
使用ForkJoin Framework集在Java 7.0中发布这是一个很好的练习。它正是你要找的。您只需将(fork)递归合并任务提交到池中,并在完成后加入结果。
您可以下载JSR 166 Binary。有关详细信息,请this是一篇不错的文章
编辑以解决您的评论:
如果您想自己实现它,则不希望每个子列表都有一个新的Thread。您可以想象,将对给定数组中的许多分区进行排序,以使每个分区的线程变得更大(假设数组足够大)。相反,您需要为每个分区数组创建一个线程,您将实际进行合并工作。 ForkJoin为您完成此任务,使用FJ池的一个好处是它将重用线程而不是为子流程合并创建新线程。
答案 1 :(得分:0)
在java 7中使用RecursiveAction类
public class ParallelMergeSort {
private static final ForkJoinPool threadPool = new ForkJoinPool();
private static final int SIZE_THRESHOLD = 16;
public static void sort(Comparable[] a) {
sort(a, 0, a.length-1);
}
public static void sort(Comparable[] a, int lo, int hi) {
if (hi - lo < SIZE_THRESHOLD) {
insertionsort(a, lo, hi);
return;
}
Comparable[] tmp = new Comparable[a.length];
threadPool.invoke(new SortTask(a, tmp, lo, hi));
}
/**
* This class replaces the recursive function that was
* previously here.
*/
static class SortTask extends RecursiveAction {
Comparable[] a;
Comparable[] tmp;
int lo, hi;
public SortTask(Comparable[] a, Comparable[] tmp, int lo, int hi) {
this.a = a;
this.lo = lo;
this.hi = hi;
this.tmp = tmp;
}
@Override
protected void compute() {
if (hi - lo < SIZE_THRESHOLD) {
insertionsort(a, lo, hi);
return;
}
int m = (lo + hi) / 2;
// the two recursive calls are replaced by a call to invokeAll
invokeAll(new SortTask(a, tmp, lo, m), new SortTask(a, tmp, m+1, hi));
merge(a, tmp, lo, m, hi);
}
}
private static void merge(Comparable[] a, Comparable[] b, int lo, int m, int hi) {
if (a[m].compareTo(a[m+1]) <= 0)
return;
System.arraycopy(a, lo, b, lo, m-lo+1);
int i = lo;
int j = m+1;
int k = lo;
// copy back next-greatest element at each time
while (k < j && j <= hi) {
if (b[i].compareTo(a[j]) <= 0) {
a[k++] = b[i++];
} else {
a[k++] = a[j++];
}
}
// copy back remaining elements of first half (if any)
System.arraycopy(b, i, a, k, j-k);
}
private static void insertionsort(Comparable[] a, int lo, int hi) {
for (int i = lo+1; i <= hi; i++) {
int j = i;
Comparable t = a[j];
while (j > lo && t.compareTo(a[j - 1]) < 0) {
a[j] = a[j - 1];
--j;
}
a[j] = t;
}
} }