[英]Realize worker-threads for merge sort algorithm
我有一个单线程版本的合并排序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方法中添加一些东西但实际上让我感到困惑。
合并排序是一种分而治之的算法:
所以我实际上会为每个子列表启动一个线程。 你怎么看? 如何根据给定实现并行化合并排序? 有谁知道为什么我应该编辑排序方法?
这是使用ForkJoin Framework集在Java 7.0中发布的一个很好的练习。 它正是你要找的。 您只需将(fork)递归合并任务提交到池中,并在完成后加入结果。
您可以下载JSR 166二进制文件 。 有关更多信息, 这是一篇很好的文章
编辑以解决您的评论:
如果你想自己实现它,你不希望每个子列表都有一个新的Thread。 您可以想象,将对给定数组中的许多分区进行排序,以使每个分区的线程变得更大(假设数组足够大)。 相反,您需要为每个分区数组创建一个线程,您将实际进行合并工作。 ForkJoin为您完成此任务,使用FJ池的一个好处是它将重用线程而不是为子流程合并创建新线程。
在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;
}
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.