Рассмотрим этот (полностью надуманный) код Java:
final List<Integer> s = Arrays.asList(1, 2, 3);
final int[] a = new int[1];
a[0] = 100;
s.parallelStream().forEach(i -> {
synchronized (a) {
a[0] += i;
}
});
System.out.println(a[0]);
Гарантируется ли этот код для вывода "106"?
Кажется, что это не так, если нет Отношение «случается до» , установленное parallelStream()
, благодаря которому мы можем точно знать, что при первом доступе к a[0]
в лямбда-выражении будет 100
, а не ноль (согласно моему пониманию модели памяти Java).
Но Collection.parallelStream()
не задокументировано для установления такой связи ...
Тот же вопрос можно задать для завершения вызова метода parallelStream()
.
Итак, я что-то упустил, или это правда, что для корректности приведенный выше код должен выглядеть примерно так:
final List<Integer> s = Arrays.asList(1, 2, 3);
final int[] a = new int[1];
synchronized (a) {
a[0] = 100;
}
s.parallelStream().forEach(i -> {
synchronized (a) {
a[0] += i;
}
});
synchronized (a) {
System.out.println(a[0]);
}
Или ... parallelStream()
действительно предоставляет эти отношения между случаем и до , и это просто вопрос какой-то недостающей документации?
Я спрашиваю, потому что с точки зрения разработки API кажется (по крайней мере мне), что это было бы логичносделать... аналогично Thread.start()
и т. д.