Java 정적 이니셜 라이저 스레드는 안전합니까?
정적 코드 블록을 사용하여 레지스트리의 일부 컨트롤러를 초기화하고 있습니다. 내 질문은 따라서이 정적 코드 블록이 클래스가 처음로드 될 때 절대적으로 한 번만 호출된다는 것을 보장 할 수 있습니까? 이 코드 블록이 언제 호출되는지 보장 할 수 없다는 것을 이해합니다. 클래스 로더가 처음로드 할 때 추측합니다. 정적 코드 블록의 클래스에서 동기화 할 수 있다는 것을 알고 있지만 실제로는 이것이 실제로 어떻게됩니까?
간단한 코드 예제는 다음과 같습니다.
class FooRegistry {
static {
//this code must only ever be called once
addController(new FooControllerImpl());
}
private static void addController(IFooController controller) {
// ...
}
}
아니면 내가해야합니까;
class FooRegistry {
static {
synchronized(FooRegistry.class) {
addController(new FooControllerImpl());
}
}
private static void addController(IFooController controller) {
// ...
}
}
예, Java 정적 초기화 프로그램은 스레드로부터 안전합니다 (첫 번째 옵션 사용).
그러나 코드가 정확히 한 번만 실행되도록하려면 단일 클래스 로더 만 클래스를로드해야합니다. 정적 초기화는 클래스 로더 당 한 번 수행됩니다.
게으른 초기화에 사용할 수있는 트릭입니다.
enum Singleton {
INSTANCE;
}
또는 Java 5.0 이전
class Singleton {
static class SingletonHolder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton instance() {
return SingletonHolder.INSTANCE;
}
}
SingletonHolder의 정적 블록은 스레드 안전 방식으로 한 번 실행되므로 다른 잠금이 필요하지 않습니다. instance ()를 호출 할 때만 SingletonHolder 클래스가로드됩니다.
일반적인 상황에서는 정적 이니셜 라이저의 모든 것이 해당 클래스를 사용하는 모든 것보다 먼저 발생하므로 일반적으로 동기화가 필요하지 않습니다. 그러나 클래스는 정적 intiailiser가 호출하는 모든 항목에 액세스 할 수 있습니다 (다른 정적 초기자를 호출하는 것을 포함하여).
클래스는로드 된 클래스에 의해로드 될 수 있지만 반드시 즉시 초기화 될 필요는 없습니다. 물론 클래스는 클래스 로더의 다중 인스턴스에 의해로드 될 수 있으며 같은 이름을 가진 여러 클래스가 될 수 있습니다.
예, 일종의
static
초기화는 그래서 정의 그것의 스레드 안전에 의해 한 번 호출됩니다 - 당신은 두 개 이상의 호출이 필요할 것 static
조차 얻을 스레드 경합 이니셜 라이저.
즉, static
이니셜 라이저는 다른 많은 방법으로 혼란스러워합니다. 그들이 부르는 순서는 실제로 없습니다. static
이니셜 라이저가 서로 의존하는 두 개의 클래스가 있으면 혼란 스럽습니다 . 클래스를 사용하지만 static
초기화 프로그램이 설정 한 것을 사용하지 않으면 클래스 로더가 정적 초기화 프로그램을 호출한다고 보장 할 수 없습니다.
마지막으로 동기화하려는 객체를 명심하십시오. 나는 이것이 실제로 당신이 요구하는 것이 아니라는 것을 알고 있지만, addController()
스레드 안전 을 만들어야하는지 질문하지 않아야 합니다.
Yes, Static initializers are run only once. Read this for more information.
So basically, since you want a singleton instance, you should do it more or less the old-fashioned way and make sure your singleton object is initialised once and only once.
참고URL : https://stackoverflow.com/questions/878577/are-java-static-initializers-thread-safe
'programing tip' 카테고리의 다른 글
TensorFlow에서 텐서를 numpy 배열로 변환하는 방법은 무엇입니까? (0) | 2020.06.25 |
---|---|
여러 Redis 데이터베이스의 요점은 무엇입니까? (0) | 2020.06.25 |
Java에서 메모리를 비우는 방법? (0) | 2020.06.25 |
iPhone 데이터 사용량 추적 / 모니터링 (0) | 2020.06.25 |
SPAN 대 DIV (인라인 블록) (0) | 2020.06.25 |