개발하는 두더지

[Effective Java 규칙71] 초기화 지연은 신중하게 하라 본문

Java,Android

[Effective Java 규칙71] 초기화 지연은 신중하게 하라

덜지 2018. 11. 20. 18:30

[Effective Java 규칙71] 초기화 지연은 신중하게 하라

Effective Java 2/E 책과 구글링을 통해 내용을 정리하고 개인적인 견해가 포함된 글입니다.



초기화 지연(lazy initialization)은 클래스, 필드 등을 사용하는 시점에 초기화를 하는 기법입니다. 대부분의 경우에는 초기화 지연보다는 일반적으로 클래스를 생성하면서 초기화 하는 것이 좋습니다. 초기화 비용이 크고, 내부적으로 필드 사용 빈도가 적다면 초기화 지연이 적절합니다.


초기화 지연을 위해 안정적인 방법을 사용해야 합니다.


1.

초기화 지연 담당 클래스 숙어( lazy initialization holder class = Initialization-on-demand holder idiom ) 는 스레드에 안전하고 동시적 초기화 지연을 제공하고 좋은 성능을 가집니다. JVM이 LazyHolder를 실행해야 한다고 결정할 때까지 LazyHolder안에 있는 INSTANCE는 초기화 되지 않습니다. getInstance 메서드가 실행될때만 LazyHolder가 초기화됩니다.

public class Something {
private Something() {}

private static class LazyHolder {
static final Something INSTANCE = new Something();
}

public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}


2. 이중 검사 숙어 ( double check idiom, double checked locking )

public class Something {
private volatile Helper helper;
public Helper getHelper() {
Helper localRef = helper;
if(localRef == null) {
synchronized (this) {
localRef = helper;
if(localRef == null) {
helper = new Helper();
}
}
}
return helper;
}
}

초기화 되지 않았을 때만 락을 걸어서 검사하고, 초기화가 되었으면 synchronized 키워드를 사용하지 않기때문에 락을 걸어야 하는 비용을 줄일 수 있다. 필드는 반드시 volatile 로 선언해야 한다. 이 키워드가 있어야 여러 스레드가 싱글톤 인스턴스를 올바르게 다룰 수 있습니다. 즉 thread-safe 하게 만들 수 있습니다.















Comments