더북(TheBook)

다음은 수행할 수 없는 일의 예다. 문자열 스트림에서 모든 짧은 단어의 수를 세려 한다고 하자.


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 참고).

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.