Сделайте итеративный многопоточный метод - PullRequest
0 голосов
/ 08 июня 2018

У меня есть метод с именем find_duplicates(List<DP> dp_list), который принимает ArrayList моего пользовательского типа данных DP.У каждого DP есть строка с именем «ID», которая должна быть уникальной для каждого DP.

Мой метод просматривает весь список и добавляет любой DP, у которого нет уникального идентификатора, в другой ArrayList, который возвращается, когдаМетод заканчивается.Это также изменяет логическое поле isUnique DP с true на false.

Я хочу сделать этот метод многопоточным, поскольку каждая проверка элемента не зависит от проверок других элементов.Но для каждой проверки поток должен прочитать dp_list.Можно ли дать доступ на чтение одного и того же списка к разным потокам одновременно?Можете ли вы предложить метод, чтобы сделать его многопоточным?

Прямо сейчас мой код выглядит следующим образом -

List<DP> find_duplicates(List<DP> dp_list){
    List<DP> dup_list = new ArrayList<>();
    for(DP d: dp_list){
        -- Adds d to dup_list and sets d.isUnique=false if d.ID is not unique --
    }
    return dup_list;
}

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Есть лучшие способы, которыми вы можете сделать это.Все, что вам нужно сделать, это получить блокировку list и проверить, существует ли элемент, с последующей дальнейшей обработкой.

void find_duplicates(List<DP> dp_list, DP item){

    synchronized(dp_list){
        if(dp_list.contains(item)){
            //Set your flags
        }
    }


}
0 голосов
/ 08 июня 2018

Кажется, вы хотите использовать параллелизм, где это возможно.Прежде всего, я бы посоветовал измерить ваш код, будь то с императивным подходом или с использованием последовательного потока , а затем , если вы думаете, что параллельная работа может действительно помочь улучшить производительность, тогда вы можетеиспользовать параллельный поток. см. Здесь, чтобы помочь решить, когда использовать параллельный поток .

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

List<DP> find_duplicates(List<DP> dp_list){
        List<DP> dup_list = dp_list.stream() //dp_list.parallelStream()
                .collect(Collectors.groupingBy(DP::getId))
                .values()
                .stream()
                .filter(e -> e.size() > 1)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        dup_list.forEach(s -> s.setUnique(false));
        return dup_list;
}

Это будетсоздайте поток из источника, затем сгруппируйте элементы по их идентификаторам и сохраните все элементы с повторяющимся идентификатором, а затем, наконец, установите для поля isUnique значение false;

0 голосов
/ 08 июня 2018
List<DP> unique = dp_list.stream().parallel().distinct().collect(Collectors.toList());

Тогда просто найдите разницу между исходным списком и списком уникальных элементов, и у вас есть дубликаты.

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

...