对于我的类,我必须在多线程中实现合并排序算法,并将其时间与单线程版本进行比较。我知道它应该更快,但我得到的时间不然。对于大小为1000000+的阵列,多线程版本变得更快,即便如此,它也没有显着差异。 我正在提供我正在使用的代码。难道我做错了什么?我在多线程方面没有多少经验
public Sorter() {
public void mergeSortMultiThread(int[] array, int start, int end){
if(start < end){
// Find the middle point
int m = (start+end)/2;
Thread t1 = new Thread(() -> mergeSortSequence(array, start, m));
t1.start();
mergeSortSequence(array , m+1, end);
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Merge the sorted halves
merge(array, start, m, end);
}
}
public void mergeSortSnngleThread(int[] array, int start, int end){
if(start < end){
// Find the middle point
int m = (start+end)/2;
// Sort first and second halves
mergeSortSequence(array, start, m);
mergeSortSequence(array , m+1, end);
// Merge the sorted halves
merge(array, start, m, end);
}
}
private void merge(int arr[], int l, int m, int r)
{
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
/* Create temp arrays */
int L[] = new int [n1];
int R[] = new int [n2];
/*Copy data to temp arrays*/
for (int i=0; i<n1; ++i)
L[i] = arr[l + i];
for (int j=0; j<n2; ++j)
R[j] = arr[m + 1+ j];
/* Merge the temp arrays */
// Initial indexes of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarry array
int k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
/* Copy remaining elements of L[] if any */
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
/* Copy remaining elements of R[] if any */
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
}
答案 0 :(得分:4)
你犯了两个基本错误:
首先创建线程,创建线程在时间上是昂贵的,因此最好使用线程池或标准java api:ExecutorService
。
另一个基本错误是您使用的线程数,当您进行递归调用时,您不断增加处理器中的线程数,您必须从一定数量的线程中实现,工作并没有真正并行化,因为处理器没有足够的内核来同时执行这项工作,但多线程管理引入的过载确实会影响性能。
这个答案可以帮助您了解如何利用多线程:Multithreaded merge sort, adding additional threads
答案 1 :(得分:2)
不是动态创建线程,而是将数组拆分为k个块,然后使用k个线程对每个k块进行排序,然后在每个线程完成它的任务时合并排序的块。合并也可以是多线程的。假设您使用4个块,并使用4个线程。每个线程0,1,2,3对其“块”进行排序。线程1和3一旦其块被分类就终止。在线程2对其块进行排序之后,它等待线程3完成然后合并块2和3.在线程0对其块进行排序后,它等待线程1完成然后合并块0和1,然后等待线程2到完成然后将合并的0 + 1块与合并的2 + 3块合并。