Search code examples
javamergesortconcurrent.futures

Merge Sort with Java Futures


I am trying to write a merge sort algorithm that uses java futures. The current program I have using futures is slower then a standard merge sort algorithm. I would prefer to use java futures over fork join as I am currently learning about java futures. I am trying to work in parallel streams and was advice it was best to have half the work in the future and half the work in the main thread.


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MParallelSorter1 implements Sorter {
    
    private static final ExecutorService pool = Executors.newFixedThreadPool(10);
    private MSequentialSorter s = new MSequentialSorter();

  @Override
  public <T extends Comparable<? super T>> List<T> sort(List<T> list) {
      
      if(list.size() < 2){
          
          return list;
      }else {
      int mid = list.size()/2;
      Future<List<T>> left = pool.submit(()->sort(list.subList(0, mid)));
      List<T> right = sort(list.subList(mid, list.size()));
      
      return mergeSort(get(left), right);
          
      }
    }
  

  public <T extends Comparable<? super T>> List<T> mergeSort(List<T> left, List<T> right) {
        int i = 0, j = 0, k = 0;
        List<T> toReturn = new ArrayList<>();
            
  
      while (i < left.size() && j < right.size()) {
            if (left.get(i).compareTo(right.get(j)) < 0)  {
                toReturn.add(k, left.get(i));
                i++;
            } else {
                toReturn.add(k, right.get(j));
                j++;
            }
            k++;
        }

        while (i < left.size()) {
            toReturn.add(k, left.get(i));
            i++;
            k++;
        }

        while (j < right.size()) {
            toReturn.add(k, right.get(j));
            j++;
            k++;
        }
  
        
    return toReturn;   
}


  public static <T> T get (Future<T> f) {
      try {
          return f.get();
      }
      catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new Error(e);
    }
    catch (ExecutionException e) {
        Throwable t = e.getCause();
        if(t instanceof RuntimeException rt) {
            throw rt;
        }
        if(t instanceof Error et) {
            throw et;
        }
        throw new Error("Unexpected Checked Exception", t);
    }
    
  }
}```

Solution

  • Have you tried changing Executors.newFixedThreadPool(10) to Executors.newWorkStealingPool()?