Может ли лямбда forEach привести к состоянию гонки? - PullRequest
0 голосов
/ 26 апреля 2018

Я не уверен в том, как лямбды работают на практике, и я обеспокоен тем, что при определенных обстоятельствах лямбды могут привести к ошибкам, таким как ConcurrentModificationExceptions, если вы используете их неправильно, что, по-видимому, свидетельствует о состоянии гонки.
Рассмотрим код ниже.

private class deltaCalculator{
    Double valueA;
    Double valueB;

    //Init delta
    volatile Double valueDelta = null;

    private void calculateMinimum(List<T> dataSource){
        dataSource.forEach((entry -> {
            valueA = entry.getA();
            valueB = entry.getB();
            Double dummyDelta;

            dummyDelta = Math.abs(valueA - valueB);

            if(valueDelta == null){
                setDelta(dummyDelta);
            }else {
                setDelta((valueDelta > dummyDelta) ? dummyDelta : valueDelta);
            }
        }));
    }

    private void setDelta(Double d){
        this.valueDelta = d;
    }
}

Как работает цикл forEach? Передаются ли разные вызовы разным потокам, где JVM считает это целесообразным, открывая возможность состояния гонки, которое может привести к неверному вычислению минимума?
Если нет, почему лямбда forEach может генерировать исключение ConcurrentModificationException?

1 Ответ

0 голосов
/ 26 апреля 2018

Вы получите исключение ConcurrentModificationException, если попытаетесь изменить коллекцию, для которой вы выполняете итерацию, во время выполнения цикла для каждого цикла. Это можно сделать в отдельном потоке целиком, но гораздо чаще это происходит при попытке изменить коллекцию в теле цикла.

Передаются ли разные вызовы разным потокам, где JVM считает это целесообразным, открывая возможность состояния гонки, которое может привести к неверному вычислению минимума?

Нет. В приведенном выше примере многопоточность не выполняется.

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