Является ли фреймворк Fork-Join в Java 8 лучшим вариантом?

У меня есть сценарий, как будто я хочу прочитать электронную таблицу, состоящую примерно из 2000 записей, и ввести ее в базу данных.

В настоящее время мы используем фреймворк Executor. У нас есть ограничение, что количество задач должно быть только 5. Каждая задача считывает 20 строк из Excel. Мы предоставляем начальный индекс и конечный индекс строк, которые должны быть прочитаны из Excel для каждой задачи.

Скажем, в настоящее время
Задача 1 обрабатывает 1–20
Задача 2 обрабатывает 21–40
Задача 3 обрабатывает 41–60
Задача 4 обрабатывает 61–80< br> Задача-5 обрабатывает 81-100

Если Задача-1 завершает свое выполнение, она занимает следующие 20 строк со 101-120.
Предположим, что если Задача-2 завершится раньше, чем Задача-1, она начинайте читать со 121-140, а не со 101-120.

Могу ли я более эффективно справиться с этим сценарием в рамках Fork-Join только с ограничением 5 задач и каждой задачей 20 строк?

Нужно немного разобраться в проблемах с производительностью.


person dove4evr    schedule 12.02.2016    source источник
comment
Не вижу смысла менять фреймворк.   -  person Holger    schedule 12.02.2016
comment
Прямо сейчас обработка задач выполняется кодом, который мы разработали, то есть, если задача 1 завершена, выделение следующей задачи выполняется пользовательским кодом. Есть ли у фреймворка fork-join какой-либо эффективный способ справиться с этим самостоятельно? А также мы вставляем задержку, чтобы дождаться завершения всех задач, чтобы получить результаты. Справляется ли с этим инфраструктура fork-join сама по себе?   -  person dove4evr    schedule 15.02.2016


Ответы (1)


Нет необходимости переключать пул потоков. Чтобы сделать нагрузку более сбалансированной, вы можете просто сохранить атомарную переменную, которая указывает на первую незанятую строку:

AtomicInteger currentRow = new AtomicInteger(); // shared between tasks
final int maxRow = 2000;
final int batchSize = 20;

// Inside every task:
while(true) {
    int row = currentRow.getAndAdd(batchSize);
    if(row >= maxRow) return;
    int from = row+1;
    int to = Math.min(row+batchSize, maxRow);
    // process rows from..to; it's guaranteed that other threads
    // do not process the same rows.
}

Тело каждой задачи абсолютно одинаково. Также эта реализация не зависит от количества созданных задач. Если позже вы решите иметь 3 задачи или 7 задач, просто отрегулируйте размер пула потоков и отправьте больше (или меньше) задач.

person Tagir Valeev    schedule 12.02.2016
comment
В настоящее время эта структура используется для чтения из базы данных и записи в электронную таблицу Google. Проблема в том, что когда мы пишем, первая задача извлекает 100 строк из базы данных, фильтрует данные на основе пользовательской логики и записывает только полученные строки в электронную таблицу. Поэтому, чтобы вторая задача начала запись, нам нужно дождаться завершения первой задачи, чтобы узнать, с какой строки вторая задача должна начать запись. Поэтому мне было интересно, справится ли инфраструктура fork-join с этой ситуацией сама по себе. Как работает алгоритм кражи работы в Fork-join? - person dove4evr; 16.02.2016