[英]Merge-sort using Multi-threading
我嘗試使用多線程並行化合並排序,這是我的代碼(如果執行不當,請原諒,我不在乎程序的空間復雜性)。 我正在實現排序數組。我的問題是:此過程是否會真正減少對大型數組進行排序所需的時間?需要進行哪些修改才能使其高效使用?
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Merge {
public static int[] inputArray;
public static int[] arr1;
public static int[] arr2;
public static int[] arr3;
public static int t1_status=0;
public static int t2_status=0;
public static void main(String[] args) throws IOException{
System.out.println("Enter the length of the array");
Scanner in =new Scanner(System.in);
int arraySize=in.nextInt();
inputArray = new int[arraySize];
Random rand=new Random();
for(int i=0;i<arraySize;i++)
{
inputArray[i]=rand.nextInt(100);
}
//diving the original array into two subarrays
arr1=Arrays.copyOfRange(inputArray, 0, inputArray.length/2);
arr2=Arrays.copyOfRange(inputArray, (inputArray.length)/2,inputArray.length);
//printing the original array
System.out.print("The original array is array is ");
for(int h:inputArray)
{
System.out.println(h);
}
Thread t1=new Thread(new Runnable(){
public void run()
{
mergeSort(arr1);
System.out.println("t1 started");
}
});
Thread t2=new Thread(new Runnable(){
public void run()
{
mergeSort(arr2);
System.out.println("t2 started");
}
});
//starting threads
t1.start();
t2.start();
try {
t1.join();
t2.join();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(t1.isAlive())
{
t1_status=1;
}
if(t2.isAlive())
{
t2_status=1;
}
t1.stop();
t2.stop();
arr3=new int[inputArray.length];
merge(arr3,arr1,arr2);//merging arr1 and arr2.At this point both arr1 and arr2 are sorted.
System.out.println("The sorted array is ");
for(int m:arr3)
{
System.out.print(m);
System.out.print(" ");
}
System.out.println(" ");
}
static void mergeSort(int[] A)
{
if (A.length > 1)
{
int q = A.length/2;
int[] leftArray = Arrays.copyOfRange(A, 0, q);
int[] rightArray = Arrays.copyOfRange(A,q,A.length);
mergeSort(leftArray);
mergeSort(rightArray);
merge(A,leftArray,rightArray);
}
}
//merge function
static void merge(int[] a, int[] l, int[] r) {
int totElem = l.length + r.length;
int i,li,ri;
i = li = ri = 0;
while ( i < totElem) {
if ((li < l.length) && (ri<r.length)) {
if (l[li] < r[ri]) {
a[i] = l[li];
i++;
li++;
}
else {
a[i] = r[ri];
i++;
ri++;
}
}
else {
if (li >= l.length) {
while (ri < r.length) {
a[i] = r[ri];
i++;
ri++;
}
}
if (ri >= r.length) {
while (li < l.length) {
a[i] = l[li];
li++;
i++;
}
}
}
}
if(t1_status==1){arr1=a;}
else if(t2_status==1){arr2=a;}
else{arr3=a;}
}
}
是的,它可以提供幫助,這在很大程度上取決於您擁有多少個內核以及陣列的大小。 生成線程和協調工作不是免費的。 關於實際上有多少個並行線程有用的地方很柔和。
我認為您做的太少了,但是這很容易過大:由於該進程受CPU限制,因此每個核心都需要一個線程。
固定線程池/執行器在這里很方便。
在CSE373上查看一些性能提升的示例:數據結構和算法/ MergeSort 。
將兩個半部分分別放在單獨的線程中是一個不錯的開始,但是您也可以通過合並利用並行性。
另外,您也應該並行地並行執行子分類……但是要跟蹤遞歸的深度,並在已經使用完所有內核時停止創建新線程。 為這些微小的小葉排序創建新線程是巨大的開銷。
全部一起:
請參見Collections.parallelSort()和Fork / Join框架javadoc。
足夠小的數組在單線程上按舊排序,但是當足夠大時(我認為是8192),parallelSort將使用ForkJoinPool默認池(與內核數量一樣多的線程)進行分而治之。
僅使用2個線程可能會使速度加倍,但不會更多。
僅供參考,啟動器線程也應該起作用,而不僅僅是坐在那里加入。 例如,它可以采用第二線程的工作。 然后只加入一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.