Странная ситуация с arraylist и parallelStream - PullRequest
0 голосов
/ 28 января 2019

У меня есть параллельный поток, потому что задача очень медленная, я вставлю код ниже.Ситуация такова.

У меня есть arrayList, мне нужно что-то сделать с каждым объектом в этом списке (это медленно) и добавить объект во временный список, процесс в потоке заканчивается нормально, ядумаю, потому что я вижу каждый объект, обработанный с помощью журналов.

Когда поток заканчивается, иногда временный список имеет n-1 объектов или один как ноль.

Есть идеи?

В этом примере кода ошибок не происходит, но логика та же, но без бизнес-логики.

public class SampleCode {
    public List<SomeObject> example(List<SomeObject> someObjectList) {
        List<SomeObject> someObjectListTemp = new ArrayList<>();
        someObjectList.parallelStream().forEach(someObject -> {
            List<ExtraData> extraDataList = getExtraData(someObject.getId());
            if (extraDataList.isEmpty()) {
                someObjectListTemp.add(someObject);
            } else {
                for (ExtraData extraData : extraDataList) {
                    SomeObject someObjectTemp = null;
                    someObjectTemp = (SomeObject) cloneObject(someObject);
                    if (extraData != null) {
                        someObjectTemp.setDate(extraData.getDate());
                        someObjectTemp.setData2(extraData.getData2());
                    }
                    if (someObjectTemp == null) {
                        System.out.println("Warning null object"); //I NEVER see this
                    }
                    someObjectListTemp.add(someObjectTemp);
                    System.out.println("Added object to list"); //I Always see this the same times as elements in original list
                }
            }
        });

        if (someObjectListTemp.size() < 3) {
            System.out.println("Error: There should be at least 3 elements"); //Some times one object is missing in the list
        }

        for (SomeObject someObject : someObjectListTemp) {
            if (someObject == null) {
                System.out.println("Error: null element in list"); //Some times one object is null in the list
            }
        }

        return someObjectListTemp;
    }

1 Ответ

0 голосов
/ 28 января 2019

Не могли бы вы попробовать использовать метод flatMap вместо foreach?flatMap берет список списков и помещает все их элементы в один список.

Таким образом, вы не используете другой ArrayList для хранения ваших временных объектов.Я чувствую, что это может быть проблемой, потому что parallelStream является многопоточным и ArrayList не синхронизируется

List<SomeObject> someObjectListTemp = someObjectList.parallelStream()
    .map(so -> processSomeObject(so)) // makes a stream of lists (Stream<List<SomeObject>>)
    .flatMap(Collection::stream) // groups all the elements of all the lists in one stream (Stream<Someobject>)
    .collect(Collectors.toList()); // transforms the stream into a list (List<SomeObject>)

И вставьте ваш код в отдельный метод processSomeObject, который возвращает список SomeObject:

static List<SomeObject> processSomeObject(SomeObject someObject) {
    List<ExtraData> extraDataList = getExtraData(someObject.getId());
    List<SomeObject> someObjectListTemp = new ArrayList<>();
    if (extraDataList.isEmpty()) {
        someObjectListTemp.add(someObject);
    } else {
        for (ExtraData extraData : extraDataList) {
            SomeObject someObjectTemp = (SomeObject) cloneObject(someObject);
            if (extraData != null) {
                someObjectTemp.setDate(extraData.getDate());
                someObjectTemp.setData2(extraData.getData2());
            }
            someObjectListTemp.add(someObjectTemp);
            System.out.println("Added object to list");
        }
    }

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