다음은 수행할 수 없는 일의 예다. 문자열 스트림에서 모든 짧은 단어의 수를 세려 한다고 하자.
int[] shortWords = new int[12];
words.parallel().forEach(
s -> { if (s.length() < 12) shortWords[s.length()]++; });
// 오류 — 경쟁 조건!
System.out.println(Arrays.toString(shortWords));
이는 아주 나쁜 코드다. forEach에 전달된 함수는 다수의 스레드에서 동시에 실행되어 공유 배열을 업데이트한다. 이 상황은 전형적인 경쟁 조건race condition이다. 이 프로그램을 여러 번 실행하면, 매번 실행할 때마다 다른 개수를 얻고 각각도 잘못된 결과일 것이다.
병렬 스트림 연산에 전달하는 함수가 스레드에 안전함을 보장하는 일은 여러분의 책임이다. 이 예제에서는 카운터로 AtomicInteger 객체의 배열을 사용할 수 있다(연습문제 12 참고). 다른 방법으로 단순히 스트림 라이브러리의 기능을 사용하고 문자열을 길이에 따라 그룹으로 묶을 수 있다(연습문제 13 참고).