Java MergeSort使用多线程加速

时间:2013-05-10 23:12:38

标签: java multithreading mergesort

我正在尝试使用多线程实现Mergesort的一个版本。首先,我知道这里有十亿个线程(给予或接受......),而且我读了一些但无济于事!我试图表明并行使用线程可以加快进程速度。然而,我遇到的问题是我的代码没有显示和加速,事实上,恰恰相反。

有一个帖子,我的时间是成千上万的。有两个,我的时间增加到几十万,然后有4个线程,我的时间接近7个数字。我最初的想法是使用join()方法,并确保它在正确的位置,并且已经这样做,但没有成功。

非常感谢任何帮助,并且示例命令行参数类似于;

java working 16 4(4个主题)。

对整个过程中缺乏评论表示抱歉!

import java.util.*;

class working
{
  private static int sizeVector;
  private static int noThreads;
  static void sort(int[] input)
  {
    mergeSort(input, 0, input.length - 1, noThreads);
  }

  static void mergeSort(int[] array, int low, int high, int noThreadsUp)
  {
    //private int noThreadsUp;
    if (low < high)
    {
      int mid = (low+high)/2;
      if (noThreadsUp > 1)
      {
        NewThread td = new NewThread(array, low, mid, noThreadsUp/2);
        td.start();
        /*try{
        td.join();
        }catch(Exception e){}*/
        mergeSort(array, mid+1, high, noThreadsUp/2);
                try{
        td.join();//UNSURE WHERE THIS SHOULD BE
        }catch(Exception e){}
        merge(array, low, mid, high);

      }
      else
      {
      mergeSort(array, low, mid, noThreadsUp/2); 
      mergeSort(array, mid+1, high, noThreadsUp/2);
      merge(array, low, mid, high);
      }
    }
  }

  static void merge(int[] array, int low, int mid, int high)
  {
    int[] temp = new int[high - low + 1];
    int left = low;
    int right = mid+1;
    int k = 0;
    while (left <= mid && right <= high)
    {
      if(array[left] < array[right])
      {
        temp[k] = array[left];
        left = left+1;
      }
      else
      {
        temp[k] = array[right];
        right = right + 1;
      }
      k = k + 1;
    }
    if (left <= mid)
    {
      while(left <= mid)
      {
        temp[k] = array[left];
        left = left + 1;
        k = k + 1;
      }
    }
    else if (right <= high)
    {
      while(right <= high)
      {
        temp[k] = array[right];
        right = right + 1;
        k = k + 1;
      }
    }
    for (int m = 0; m < temp.length; m++)
    {
      array[low+m] = temp[m];

  }
}
  static int[] readInputArray()
  {

    int[] a = new int[sizeVector];
    for (int i = 0; i < sizeVector; i++)
    {
      Random generator = new Random();
      a[i] = generator.nextInt();
    }
    return a;
  }

  static void printArray(int[] array)
  {
    for(int i = 0; i<array.length; i++)
      System.out.println(array[i]);
  }

  public static void main(String[] args)
  {
    sizeVector = Integer.parseInt(args[0]);
    noThreads = Integer.parseInt(args[1]);
    int[] inputArray = readInputArray();
    System.out.println("INPUT ARRAY: ");
    printArray(inputArray);
    long startTime = System.nanoTime();
    sort(inputArray);
    long endTime = System.nanoTime();
    long finalTime = endTime - startTime;

    System.out.println("SORTED ARRAY: ");
    printArray(inputArray);      
    System.out.println("Time: " + finalTime);
  }

static class NewThread extends Thread 
  {
    private int low;
    private int mid;
    private int[] array;
    private int noThreadsDown;
    //private int threads;
    public NewThread(int[] array, int low, int mid, int noThreadsDown) 
    {
      this.low = low;//Ensure using the right start
      this.mid = mid;//Ensure using the right end
      this.array = array;
      this.noThreadsDown = noThreadsDown;
      //this.threads = threads;
    }
    public void run() 
    {

      mergeSort(array, low, mid, noThreadsDown/2);
      System.out.println(noThreadsDown);
    }
  }//End NewThread
}

2 个答案:

答案 0 :(得分:1)

最好在java 7中使用RecurssionAcition类,它左右分为两部分。

Sum left  = new Sum(array, low, mid);
Sum right = new Sum(array, mid, high);
left.fork();
long rightAns = right.compute();
long leftAns   = left.join();
return leftAns + rightAns;

答案 1 :(得分:0)

这里有一些有用的代码。

public class TestMergeSort{

    public static void main(String[] args){

        // Threaded merge sort (and printing)
        int[] toSort = {191,2,3,5,6,7,5,3,21,3,4};
        printArr(toSort);  
        concurrentMergeSort(toSort); 
        printArr(toSort);  
    }

    public static void concurrentMergeSort(int[] toSort){
        int[] tmpArray = new int[toSort.length];

        try{
            // Start the mergesort
            ConcurrentMergeSort sort = new ConcurrentMergeSort(toSort, tmpArray, 0, toSort.length - 1);
            sort.start();
            sort.join();

        } catch(InterruptedException e){
            e.printStackTrace();
        }

    }

    public static void printArr(int[] a){
        for(int i = 0; i < a.length; i++){
            System.out.print(a[i] + " ,");
        }
        System.out.println();
    }
}



public class ConcurrentMerge extends Thread{
    private int[] a;
    private int[] tmpArray;
    private int leftPos;
    private int rightPos;
    private int rightEnd;

    public ConcurrentMerge(int[] a, int[] tmpArray, int leftPos, int rightPos, int rightEnd){
        this.a = a;
        this.tmpArray = tmpArray;
        this.leftPos = leftPos;
        this.rightPos = rightPos;
        this.rightEnd = rightEnd; 
    }

    public void run(){
        int leftEnd = rightPos - 1;
        int tmpPos  = leftPos;
        int numElements = rightEnd - leftPos + 1;

        // Main loop
        while( leftPos <= leftEnd && rightPos <= rightEnd )
            if( a[ leftPos ] <= a[ rightPos ] )
                tmpArray[ tmpPos++ ] = a[ leftPos++ ];
            else
                tmpArray[ tmpPos++ ] = a[ rightPos++ ];

        // Copy rest of the left half
        while( leftPos <= leftEnd )  
            tmpArray[ tmpPos++ ] = a[ leftPos++ ];

        // Copy rest of the right half
        while( rightPos <= rightEnd ) 
            tmpArray[ tmpPos++ ] = a[ rightPos++ ];

        // Copy tmpArray back
        for( int i = 0; i < numElements; i++){
            a[ rightEnd ] = tmpArray[ rightEnd-- ];
        }
    }

}


import java.util.Arrays;

public class ConcurrentMergeSort extends Thread{

    private int[] a;
    private int[] tmpArray;
    private int left;
    private int right;

    public ConcurrentMergeSort(int[] a, int[] tmpArray, int left, int right){
        this.a = a;
        this.tmpArray = tmpArray;
        this.left = left;
        this.right = right; 
    }

    public void run(){
        if(this.left < this.right){
            try{
                int center = ( this.left + this.right ) / 2;
                ConcurrentMergeSort p = new ConcurrentMergeSort(this.a, this.tmpArray, this.left, center);
                ConcurrentMergeSort q = new ConcurrentMergeSort(this.a, this.tmpArray, center + 1, this.right);
                ConcurrentMerge r = new ConcurrentMerge(this.a, this.tmpArray, this.left, center + 1, this.right);

                // Sort
                p.start();
                q.start();
                p.join();
                q.join();

                // Merge
                r.start();
                r.join();
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public int[] getA(){
        return this.a;
    }

}