I'm trying to implement the merge sorting using only the wait/notify synchronization. I'm aware of more high-level constructions like Fork/Join, Executors. etc. But I need to use work/notify here. Based on this https://courses.cs.washington.edu/courses/cse373/13wi/lectures/03-13/ I refactored the method parallelMergeSort()
with synchronized blocks:
public void parallelMergeSort() {
synchronized (values) {
if (threadCount <= 1) {
mergeSort(values);
values.notify();
} else if (values.length >= 2) {
// split array in half
int[] left = Arrays.copyOfRange(values, 0, values.length / 2);
int[] right = Arrays.copyOfRange(values, values.length / 2, values.length);
synchronized(left) {
synchronized (right) {
// sort the halves
// mergeSort(left);
// mergeSort(right);
Thread lThread = new Thread(new ParallelMergeSort(left, threadCount / 2));
Thread rThread = new Thread(new ParallelMergeSort(right, threadCount / 2));
lThread.start();
rThread.start();
/*try {
lThread.join();
rThread.join();
} catch (InterruptedException ie) {}*/
try {
left.wait();
right.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
// merge them back together
merge(left, right, values);
}
}
values.notify();
}
}
}
values
is an input array here.
As a result I see the performance of sorting is down and it's slower even than a single-thread sorting. I guess that a bottleneck is within two synchronization blocks of left and right parts of an array. Does someone know how to refactor it in order to make it faster than the single-thread sorting?