brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Oct 12. 2018

동시성(Concurrency)

#71 늦 초기화를 분별력 있게 사용하자

Effective Java - 동시성(Concurrency)


#71 늦 초기화를 분별력 있게 사용하자


늦 초기화(lazy initialization)는 필드의 값이 필요하게 될 때까지 초기화를 늦추는 것을 말합니다.


최적화 측면에서 보면, 클래스를 초기화하거나 인스턴스를 생성하는 비용을 줄여 주는 장점이 있습니다.

반대로 멀티 스레드 환경에서는 동기화가 중요하기 때문에 늦게 초기화되는 필드의 접근 비용은 늘어나게 됩니다.


늦 초기화의 장단점이 존재하기 때문에 분별력 있게 이용해야 하는데, 이를 위해 늦 초기화를 할 때와 안 할 때의 성능을 비교해야 합니다.

하지만 대부분의 상황에서는 늦 초기화보다 정상적인 초기화가 좋습니다.




초기화


인스턴스 필드를 정상적으로 초기화한다면 아래와 같이 구현할 수 있습니다.

#01 정상적인 초기화


늦 초기화를 위해서는 synchronized를 이용할 수 있습니다.

#02 늦 초기화


만약 static 필드에 적용할 때는 Holder 클래스를 이용할 수 있습니다.

이 Holder 클래스를 이용하는 시점에 초기화됩니다.

#03 늦 초기화 홀더 클래스


synchronized를 이용한 늦 초기화는 이미 필드가 초기화가 된 후에도 동기화를 하기 때문에, 불필요한 비용이 발생합니다.

이중-검사 이디엄은 필드가 초기화되어 있는지 먼저 검사를 하도 동기화를 하고 있습니다.

필드를 volatile로 지정해서 항상 최신 값을 유지하도록 합니다.

#04 이중-검사 이디엄


만약 반복적으로 초기화를 해도 괜찮은 필드도 늦 초기화를 할 필요가 있습니다.

이런 경우에는 단일-검사 이디엄을 이용할 수 있습니다.

#05 단일-검사 이디엄



결론은 특별한 사유가 없는한 정상적인 초기화를 해야 합니다.

인스턴스 필드 늦 초기화 : 이중-검사 이디엄

static 필드 - 늦 초기화 홀더 클래스 이디엄

반복 초기화 - 단일-검사 이디엄


매거진의 이전글 동시성(Concurrency)
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari