synchronized 키워드는 특정 메서드나 코드 블록을 한번에 한 스레드만 사용하도록 보장한다. 동기화는 스레드가 일관성이 깨진 객체를 관측할 수 없도록 할 뿐 아니라(하나의 스레드만 이용), 동기화 메서드나 동기화 블록에 진입한 스레드가 동일한 락의 보호 아래 이루어진 모든 변경의 영향을 관측할 수 있도록 보장한다(기존의 스레드가 변경한 내용을 새로운 스레드가 관측 가능).
성능을 높이기 위해서는 원자적 데이터를 읽거나 쓸 때 동기화를 피해야 한다는 이야기를 자주 들어봤을 것이다. 상호 배제성뿐 아니라 스레드 간의 안정적 통신을 위해서도 동기화는 반드시 필요하다. 즉 하나의 스레드만 이용할 수 있도록 하는 것의 용도 뿐만아니라 스레드 간의 안정적 통신을 위해서는 동기화를 사용해야 한다는 뜻이다. 자바의 메모리 모델 명세 때문이다. 메모리 모델은 한 스레드가 만든 변화를 다른 스레드가 볼 수 있게 되는 시점과, 그 절차를 규정하기 때문이다. 즉 기존의 스레드가 변경한 내용을 새로운 스레드가 알도록 하는 것을 규정한다는 것.
위의 클래스는 Thread.stop 대신 boolean 필드를 이용하여 스레드를 제어 했다. stop메서드는 안전성이 결여되어있으므로 사용하면 안된다. 위의 프로그램은 1초가 지나면 main 스레드가 stopRequested의 값을 true로 바꾸므로, 후면 스레드가 실행하는 순환문도 그 때 종료될 것 같다. 하지만 그렇지 않다.
이 프로그램의 문제는 동기화 메커니즘을 적용하지 않은 탓에 main스레드가 변경한 stopRequest의 새로운 값을 후면 스레드가 언제쯤 보게 될지 알 수가 없다는 것이다. 위의 프로그램은 아래와 같이 변경되어야 한다.
요약
'개발서적 > 이펙티브자바' 카테고리의 다른 글
[병행성]규칙68. 스레드보다는 실행자와 태스크를 이용하라 (0) | 2017.05.08 |
---|---|
[병행성]규칙67.과도한 동기화는 피하라. (0) | 2017.05.08 |
[예외]규칙65. 예외를 무시하지 마라 (0) | 2017.05.07 |
[예외]규칙64. 실패 원자성 달성을 위해 노력하라 (0) | 2017.05.07 |
[예외]규칙63. 어떤 오류인지 드러내는 정보를 상세한 메세지에 담으라 (0) | 2017.05.07 |