I've been trying to do a quick sort using ForkJoin in Java and while in works for the most part, I get a stackoverflow when each element of the array is equal.
import java.util.Comparator;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class QuickSortMultiThreading extends RecursiveAction {
private final int threshold = 50000;
private static Apartment[] arr;
private int start, end;
private static final Comparator<Apartment> comparator = new Apartment.ApartmentComparator();
public QuickSortMultiThreading(Apartment[] arr, int start, int end) {
this.arr = arr;
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if(arr.length == 0){
return;
}
if (end - start <= threshold) {
quickSort(start, end);
} else {
if(start < end)
{
int p = partition(start, end);
QuickSortMultiThreading left = new QuickSortMultiThreading(arr, start, p - 1);
QuickSortMultiThreading right = new QuickSortMultiThreading(arr, p + 1, end);
left.fork();
right.compute();
left.join();
}
}
}
static int partition(int low, int high)
{
Apartment pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (comparator.compare(arr[j], pivot) < 0) {
i++;
swap(i, j);
}
}
swap(i + 1, high);
return (i + 1);
}
private static void swap(int i, int j) {
Apartment temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private void quickSort(int low, int high) {
while (low < high) {
int pi = partition(low, high);
if (pi - low < high - pi) {
quickSort(low, pi - 1);
low = pi + 1;
} else {
quickSort(pi + 1, high);
high = pi - 1;
}
}
}
public static void main(String[] args) {
int size = 100000;
Apartment[] arr = new Apartment[size];
for (int j = 0; j < size; j++) {
int var1 = 1;
int var2 = 2;
int var3 = 3;
arr[j] = new Apartment(var1, var2, var3);
}
ForkJoinPool pool = new ForkJoinPool(12);
pool.invoke(new QuickSortMultiThreading(arr, 0, size - 1));
}
}
I also have a sequential implementation that doesn't share the same problem
import java.io.*;
import java.util.Comparator;
import java.util.Random;
class SequentialQuicksort {
static void swap(Apartment[] arr, int i, int j)
{
Apartment temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static int partition(Apartment[] arr, int low, int high, Comparator<Apartment> comparator) {
Apartment pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (comparator.compare(arr[j], pivot) < 0) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return (i + 1);
}
static void quickSort(Apartment[] arr, int low, int high, Comparator<Apartment> comparator)
{
while (low < high) {
int pi = partition(arr, low, high, comparator);
if (pi - low < high - pi) {
quickSort(arr, low, pi - 1, comparator);
low = pi + 1;
} else {
quickSort(arr, pi + 1, high, comparator);
high = pi - 1;
}
}
}
public static void main(String[] args)
{
int size = 100000;
Apartment[] arr = new Apartment[size];
for (int j = 0; j < size; j++) {
int var1 = 1;
int var2 = 2;
int var3 = 3;
arr[j] = new Apartment(var1, var2, var3);
}
quickSort(arr, 0, arr.length - 1, new Apartment.ApartmentComparator());
}
}
From what I understand the problem may come from endless recursion, but I'm not sure how to avoid in in parallel implementation