Видимость памяти в Fork-join

Брайан Гетц написал отличную статью о форк-соединении по адресу http://www.ibm.com/developerworks/java/library/j-jtp03048.html. В нем он перечисляет алгоритм сортировки слиянием, используя механизм fork-join, в котором он выполняет сортировку по двум сторонам массива параллельно, а затем объединяет результат.

Алгоритм сортирует два разных раздела одного и того же массива одновременно. Почему не AtomicIntegerArray или какой-либо другой механизм, необходимый для поддержания видимости? Какая гарантия, что один поток увидит записи, выполненные другим, или это небольшая ошибка? В качестве продолжения, Scala ForkJoinScheduler также дает эту гарантию?

Спасибо!

2 ответа

Решение

Само соединение (от ForkJoin) требует точки синхронизации, которая является наиболее важной частью информации. Точка синхронизации обеспечит видимость всех происходящих записей после указанной точки.

Если вы посмотрите на код, то увидите, где находится точка синхронизации. Это всего лишь один вызов метода invokeAll

public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
    t2.fork();
    t1.invoke();
    t2.join();
}

Здесь t2 разветвляется на другой процесс, t1 выполняет свою задачу, и этот вызывающий поток будет ожидать t2.join(). При прохождении t2. Все записи в t1 и t2 будут видны.

Редактировать: это редактирование просто для того, чтобы дать немного больше объяснения того, что я имел в виду под точкой синхронизации.

Допустим, у вас есть две переменные

int x;
volatile int y;

Каждый раз, когда вы пишете y, все записи, которые произошли до того, как вы прочитали y, будут доступны. Например

public void doWork(){
   x = 10;
   y = 5;
}

Если другой поток читает y = 5, то этот поток гарантированно читает x = 10. Это потому, что запись в y создает точку синхронизации, в которой все записи до указанной точки будут видны после записи.

При использовании пула Fork Join соединение ForkJoinTask создаст точку синхронизации. Теперь, если t2.fork() и t1.invoke(), соединение t2 гарантирует, что все записи, которые произошли ранее, будут видны. Поскольку все предыдущие записи находятся в одной структуре, это будет безопасно для видимости.

Я был бы рад объяснить дальше, если это не так ясно.

Просто предположение: слияние включает в себя присоединение к потоку, и объединение гарантирует видимость.

Вторая часть уверена; Я не знаю, как осуществляется слияние.

Другие вопросы по тегам