Итерация LinkedList с использованием потоков приводит к изменению списка результатов из-за RaceCondtion - PullRequest
0 голосов
/ 04 февраля 2019

Мы перебираем LinkedList, используя Streams в java8, и создаем другой список.Но из-за состояния гонки размер списка изменился.

List<DesInfo> InfoList = new LinkedList<>();
documentList.stream()
            .parallel()
            .forEach(document -> {
                Info descriptiveInfo = objectFactory.createDescriptiveInfo();
                List<Document> documents = new ArrayList<>();
                documents.add(document);
                descriptiveInfo.setHotelInfo(getHotelInfo(document.get(CODE), documents));
                InfoList.add(Info);
            });

Если мы запускаем этот код каждый раз, мы видим, что разный размер InfoList генерируется для одного и того же ввода documentList.Я прошел через некоторые форумы, и они упоминают, что LinkedList не является потокобезопасным, и вместо этого я выбрал любой потокобезопасный набор.Но мое требование не позволяет мне измениться помимо LinkedList.Мне нужно использовать функциональность параллельных потоков с тем же LinkedList.

Спасибо, Рагхаван

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Используйте collect вместо изменения состояния коллекции.

Сначала создайте функцию отображения:

private DesInfo documentToDesInfo(Document document){
    DesInfo info = objectFactory.createDescriptiveInfo();
    List<Document> documents = new ArrayList<>();
    documents.add(document);
    info.setHotelInfo(getHotelInfo(document.get(CODE), documents));
    return info;
}

Затем используйте ее в своем конвейере:

List<DesInfo> infoList = documentList.parallelStream()
                                     .map(this::documentToDesInfo)
                                     .collect(toCollection(LinkedList::new));
0 голосов
/ 04 февраля 2019

Вместо использования forEach используйте операции Collector и map():

List<HotelDescriptiveInfo> hotelDescriptiveInfoList = documentList.parallelStream()
    .map(document -> {
        HotelDescriptiveInfo descriptiveInfo = objectFactory.createHotelDescriptiveInfo();
        List<Document> documents = new ArrayList<>();
        documents.add(document);
        descriptiveInfo.setHotelInfo(getHotelInfo(document.get(HOTEL_CODE), documents));
        return descriptiveInfo;
    })
    .collect(Collectors.toCollection(LinkedList::new));

API Stream позаботится об обработке и не допустит условия гонки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...