스레드는 여러 활동을 동시에 수행할 수 있게 해준다. 하지만 동시성 프로그래밍은 단일 스레드 프로그래밍보다 어렵다. 잘못된 수 있는 일이 늘어나고 문제를 재현하기도 어려워지기 때문이다. 그렇다고 동시성 프로그래밍으로부터 언제까지나 도망 다닐 수는 없다. 자바 플랫폼 자체에 내재되어 있을 뿐 아니라, 오늘날 어디서나 쓰이는 멀티코어 프로세서의 힘을 제대로 활용하려면 반드시 내 것으로 만들어야만 하는 기술익 때문이다. 그래서 이번 장에는 동시성 프로그램을 명확하고 정확하게 만들고 잘 문서화하는 데 도움이 도는 조언들을 담았다.
메인 스레드가 1초 후 stopRequested를 true로 설정하고 반복문을 빠져나올 거락 생각할 수 있지만, 끝나지 않고 계속 실행됩니다.
원인은 동기화에 있습니다. 동기화 하지 않으면 메인 스레드가 수정한 값을 백그라운드 스레드가 언제쯤에나 보게 될지 보증할 수 없습니다.
num필드는 원자적으로 접근할 수 있고 어떤 값이든 허용한다. 문제는 ++연산자인데 numgernerateNum는 필드에 두 번 접근한다. 먼저 값을 읽고, 그 다음에 1증가한 값을 저장하는 것이다. 이 두 접근 사이에 다른 스레드가 들어와 값을 읽을 경우 첫번째 스레드와 똑같은 값을 돌려받게 되다. 프로그램이 잘못된 결과를 계사해내는 이런 오류를 safety failure라고 한다.
이러한 문제점들에 벗어나느 가장 좋은 방법은 가변 데이터를 공유하지 않는 것이다. 한 스레드가 데이터를 다 수정한 후 다른 스레드에 공유할 때는 해당 객체에서 공유하는 부분만 동기화해도 된다. 그럼 그 객체는 다시 수정할 일이 생기기 전까지 다른 스레드들은 동기화 없이 자유롭게 값을 이어갈 수 있다. 이러한 객체를 effective immutable이라 하며, 다른 스레드에 이런 객체를 건내는 행위는 safe publication이라 한다.
객체를 안전하게 발행하는 방법은 많다. 클래스 초기화 과정에서 객체를 정적 필드, volatile 필드, final 필드, 혹은 보통릐 락을 통해 접근하는 필드에 저장해도 되고 동시성 컬렉션에 저장하는 방법도 있다.