Я пытаюсь реализовать сортировку слияния, используя только синхронизацию wait/notify. Я знаю о более высокоуровневых конструкциях, таких как Fork/Join, Executors. и т. д. Но мне нужно использовать работу/уведомлять здесь. На основании этого https://courses.cs.washington.edu/courses/cse373/13wi/lectures/03-13/ я переработан метод parallelMergeSort()
с синхронизированными блоками:алгоритм сортировки слияния Java с wait()/notify() synchronization
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
является входным массивом здесь.
В результате я вижу, что производительность сортировки снижается, и она медленнее, чем однопоточная сортировка. Я предполагаю, что узкое место находится в двух блоках синхронизации левой и правой частей массива. Кто-нибудь знает, как реорганизовать его, чтобы сделать его быстрее, чем однопоточная сортировка?
Почему вы синхронизируете левый и правый массив? Идея состоит в том, что Threads каждый из них сортирует другую часть массива, поэтому нет необходимости в синхронизации. –
@Fank, но мне нужно подождать эти потоки перед слиянием правой и левой частей, а wait() должен находиться в секции синхронизации. –
@kolya Ну, я не думаю, что ждать() особенно полезно здесь. Wait используется, когда 1 поток хочет получить доступ к ресурсу, который может быть заблокирован другими параллельными алгоритмами потока, пытается избежать этого, работая на разных частях данных одновременно. Скорее всего, вы хотите присоединиться. Механизм Wait/notify полезен при необходимости использования Mutex или Semaphor, как для проблемы поставщика/потребителя. –