이와 같은 제약에는 이유가 있다. 람다 표현식에서 변수를 변경하는 작업은 스레드에 안전하지 않다. 일련의 병행 작업이 있고, 각 작업에서 공유 카운터를 업데이트하는 경우를 생각해보자.
int matches = 0;
for (Path p : files)
new Thread(() -> { if (p가 어떤 프로퍼티를 포함하면) matches++; }).start();//matches를 변경하는 일은 규칙에 어긋난다.
만일 이 코드가 규칙에 맞는 것이었다면, 아주 나쁜 결과를 초래했을 것이다. 다시 말해, 증가 연산 matches++가 원자적이지 않기 때문에 여러 스레드에서 이 증가 연산을 동시에 실행하면 무슨 일이 일어날지 알 수 있는 방법이 없다.
<Note>
이너 클래스 역시 자신을 감싸고 있는 유효 범위에 있는 값들을 캡처할 수 있다. 자바 8 이전에는 이너 클래스가 final 지역 변수만 접근할 수 있었다. 지금은 이 규칙이 람다 표현식과 일치하도록 완화되었다. 이너 클래스는 사실상 final인 모든 지역 변수(즉, 값이 변하지 않는 모든 지역 변수)를 접근할 수 있다.