Параллельное выполнение методов в цикле for - PullRequest
0 голосов
/ 15 мая 2018

Существует следующий метод:

public void method(Collection<BigInteger> objectIds) {
    Collection<BigInteger> allObjectIds = new HashSet<BigInteger>(objectIds);
    for(BigInteger objId : allObjectIds) {
        SomeObject obj = getObjectById(objId); // obj.getColour(): red, green or blue
        if(isFirstGroup(obj)) { // the first group
            createInFirstGroup(obj);
        } else { // the second group
            createInSecondGroup(obj);
        }
    }    
}

Ожидается получить много allObjectIds в качестве входных данных. Для повышения производительности необходимо выполнить createInFirstGroup, createInSecondGroup одновременно, учитывая следующие условия:

  1. все объекты типа SomeObject можно разделить на две группы - первую и вторую. Все входящие объекты могут быть из 1-й группы, 2-й группы или из обоих.
  2. SomeObject класс имеет поле colour, которое может быть равно «красный», «зеленый», «синий». Объекты с разными идентификаторами могут иметь одинаковые значения цвета. Таким образом, эти объекты с одинаковыми значениями цвета могут находиться внутри каждой группы (1-й, 2-й или оба). Их обработка в методах createInFirstGroup, createInSecondGroup не должна быть параллельной в случае равной группы и цвета.

Например, следующие комбинации неправильны (пара x, y):

  • нить х, у: (1-я группа, зеленая; 1-я группа, зеленая)
  • нить х, у: (2-я группа, зеленая; 2-я группа, зеленая)

Следующие комбинации являются правильными:

  • нить х, у: (1-я группа, зеленая; 2-я группа, зеленая)
  • нить х, у: (1-я группа, зеленая; 1-я группа, красная)

Как правильно (возможно, есть несколько подходящих шаблонов) портировать описанный метод public void method(Collection<BigInteger> objectIds) (его часть for-loop) в параллельный, обеспечивая оптимальное количество потоков и распределение задач (с учетом описанных условий)?

Заранее спасибо!

1 Ответ

0 голосов
/ 15 мая 2018

Я не очень четко понимаю ваши ограничения, но один общий подход - это конвейер, соединенный очередями.Вы можете использовать очередь блокировки, чтобы применить противодавление.Следующее является «актером», вдохновленным, когда каждый актер является однопоточным, получает из очереди блокировки и публикует в выходной очереди, за исключением источника и приемника.Вы можете реализовать весь конвейер в терминах этого, где будет происходить координация между источником и приемником, чтобы приемник знал, когда завершить.

  • Источник -> собирает и записывает objectIds -> в очередь
  • <- <code>getObjectById поток читает из предыдущего и пишет -> в очередь вывода
  • <- создает в групповом потоке, проверяет первую / вторую и создает -> пишет в выход
  • <- окончательные результаты чтения из предыдущих двух выходов </li>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...