You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
이번 아이템에서 이야기한 모든 초기화 기법은 기본 타입 필드와 객체 참조 필드 모두에 적용할 수 있다.
->이중검사와 단일검사 관용구를 수치 기본 타입 필드에 적용한다면, 필드의 값을 null대신 0과 비교하면 됨
짜릿한 단일검사
모든 스레드가 필드의 값을 다시 계산해도 상관없고 필드의 타입이 long, double을 제외한 다른 기본 타입이라면 volatile을 없애도 된다.
필드 접근 속도를 높여주지만, 초기화가 스레드 당 한 번 더 이뤄질 수 있다.
거의 쓰지 않음
💡 대부분의 필드는 지연시키지 말고 곧바로 초기화해야한다.
성능/ 위험한 초기화 순환 때문이다 → 올바른 지연 초기화 방식을 사용하자
- 인스턴스 필드 : 이중검사 관용구
- 정적 필드 : 지연 초기화 홀더 클래스 관용구
반복해 초기화해도 괜찮은 인스턴스 필드는 단일검사 관용구도 고려 대상
The text was updated successfully, but these errors were encountered:
지연 초기화(laze initialization)
다른 최적화와 마찬가지로, 지연 초기화에 대해 해줄 최선의 조언은
“필요할 때 까지 하지 마라”
그럼에도 지연 초기화가 필요한 때가 있다.
멀티스레드 환경에서는 지연 초기화를 하기가 까다롭다.
대부분의 상황에서 일반적인 초기화가 지연 초기화보다 낫다.
지연 초기화가 초기화 순환성을 깨뜨릴 것 같으면 synchronized를 단 접근자를 사용하자.
이상의 두 관용구는 정적 필드에도 똑같이 적용된다.
물론 필드와 접근자 메서드 선언에는 static 한정자를 추가해햐한다.
성능때문에 정적 필드를 지연 초기화해야 한다면 지연 초기화 홀더 클래스 관용구를 사용하자.
클래스는 클래스가 처음 쓰일 때 비로소 초기화된다는 특성을 이용한 관용구다. 어떻게 동작하는지 함께 보자.
getField가 처음 호출되는 순간 FieldHolder.field가 처음 읽히면서 비로소 FieldHolder 클래스 초기화를 촉발한다.
getField 메서드가 필드에 접근하면서 동기화를 전혀 하지 않으니 성능이 느려질 거리가 전혀 없다.
일반적인 VM은 오직 클래스를 초기화할 때만 필드 접근을 동기화할 것이다. 클래스 초기화가 끝난 후에는 VM이 동기화 코드를 제거하여 그 다음부터는 아무런 검사나 동기화 없이 필드에 접근하게 된다.
성능때문에 인스턴스 필드를 지연 초기화해야 한다면 이중검사 관용구를 사용하라
이 관용구는 초기화된 필드에 접근할 때의 동기화 비용을 없애준다. (Item 79)
필드의 값을 두 번 검사하는 방식으로 한 번은 동기화 없이 검사하고(필드가 아직 초기화되지 않았다는 가정 하에) 두 번째는 동기화하여 검사한다.
두 번째 검사에서도 필드가 초기화되지 않았을 때만 필드를 초기화한다.
필드가 초기화 된 후로는 동기화하지 않으므로 해당 필드는 반드시 volatile로 선언해야한다.(Item 78)
result 변수가 필요한 이유
→ 이 변수는 필드가 이미 초기화된 상황에서 그 필드를 딱 한 번만 읽도록 보장한다.
성능이 1.4배 높아진다.
이중검사를 정적필드에도 적용할 수 있지만 굳이 그럴 이유는 없다. 이보다는 지연 초기화 홀더 클래스 방식이 낫다.
이중검사의 변종
지연단일검사 관용구
->이중검사와 단일검사 관용구를 수치 기본 타입 필드에 적용한다면, 필드의 값을 null대신 0과 비교하면 됨
짜릿한 단일검사
The text was updated successfully, but these errors were encountered: