이 게시물에서는 즉시 초기화, 이중 확인 잠금 및 내부 정적 클래스 접근 방식이 있습니다. 또한 final 키워드가 싱글톤의 무결성을 보장하는 데 왜 유용한지 논의하겠습니다.
싱글톤을 사용하는 이유는 무엇입니까?한 인스턴스가 정확히 필요할 때 유용합니다. 일반적인 사용 사례에는 로깅, 구성 또는 연결 풀과 같은 공유 리소스 관리가 포함됩니다. 싱글톤은 클래스에 액세스하기 위한 여러 요청이 새 클래스를 생성하는 대신 동일한 인스턴스를 공유하도록 보장합니다.
1. 즉시 초기화: 가장 간단한 싱글톤
public final class Singleton { // Instance is created at class loading time private static final Singleton INSTANCE = new Singleton(); // Private constructor prevents instantiation from other classes private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
장점:
단점:
사용 시기: 즉시 초기화는 싱글톤 클래스가 가볍고 애플리케이션 런타임 중에 사용될 것이 확실할 때 가장 좋습니다.
지연 초기화라고도 함) 이중 확인 잠금이 스레드로부터 안전한 솔루션을 제공합니다. 최소한의 동기화를 사용하며 처음 액세스할 때만 인스턴스가 생성되도록 합니다.
public final class Singleton { // Marked as final to prevent subclassing // volatile ensures visibility and prevents instruction reordering private static volatile Singleton instance; // Private constructor prevents instantiation from other classes private Singleton() {} public static Singleton getInstance() { if (instance == null) { // First check (no locking) synchronized (Singleton.class) { // Locking if (instance == null) { // Second check (with locking) instance = new Singleton(); } } } return instance; } }
첫 번째 확인: 동기화된 블록 외부의 if(instance == null) 확인을 사용하면 getInstance()가 호출될 때마다 잠김을 방지할 수 있습니다. 이는 초기화 후 향후 호출에 대해 동기화된 블록을 우회하여 성능을 향상시킵니다.
동기화 블록: 인스턴스가 null이면 동기화 블록을 입력하면 단 하나의 스레드만 싱글톤 인스턴스를 생성하게 됩니다. 이 지점에 도달하는 다른 스레드는 경쟁 조건을 방지하기 위해 기다려야 합니다.
두 번째 확인: 동기화된 블록 내에서 인스턴스를 다시 확인하여 현재 스레드가 기다리는 동안 다른 스레드가 초기화하지 않았는지 확인합니다. 이렇게 다시 확인하면 싱글톤 인스턴스가 하나만 생성됩니다.
휘발성 키워드는 명령어 재정렬을 방지하기 위해 이중 확인 잠금 패턴에 필수적입니다. 이것이 없으면 문은 인스턴스 = new Singleton(); 완전히 초기화되기 전에 다른 스레드에 완료된 것으로 나타나 부분적으로 구성된 인스턴스가 반환될 수 있습니다. 휘발성은 일단 인스턴스가 null이 아니면 완전히 구성되어 모든 스레드에 표시되도록 보장합니다.
여기서는 하위 클래스화를 방지하기 위해 마지막 키워드가 사용됩니다. 싱글톤 클래스를 최종으로 표시하면 두 가지 주요 이점이 있습니다.
하위 클래스화 방지: 클래스를 최종 클래스로 만들어 다른 클래스가 클래스를 확장하는 것을 방지합니다. 서브클래싱으로 인해 추가 인스턴스가 발생하여 싱글톤 패턴이 깨질 수 있으므로 이렇게 하면 싱글톤 클래스의 인스턴스가 하나만 존재할 수 있습니다.
불변성 신호: final은 싱글톤 클래스가 불변성을 갖도록 의도되었으며 확장되어서는 안 된다는 점을 다른 개발자에게 명확하게 표시하는 역할을 합니다. 이렇게 하면 코드를 더 쉽게 이해하고 유지 관리할 수 있습니다.
간단히 말해서 final은 싱글톤의 무결성을 강화하고 서브클래싱으로 인한 예상치 못한 동작을 방지하는 데 도움이 됩니다.
장점:
단점:
사용 시기: 이 패턴은 싱글톤 클래스가 리소스 집약적이고 항상 필요하지 않을 수 있거나 다중 스레드 환경에서의 성능이 문제가 될 때 유용합니다.
지연 초기화에 대한 스레드로부터 안전한 대체 접근 방식은 내부 정적 클래스 패턴입니다. 이는 Java의 클래스 로딩 메커니즘을 활용하여 명시적인 동기화 없이 필요할 때만 싱글톤 인스턴스를 초기화합니다.
public final class Singleton { // Instance is created at class loading time private static final Singleton INSTANCE = new Singleton(); // Private constructor prevents instantiation from other classes private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
이 패턴에서 SingletonHelper 클래스는 getInstance()가 처음 호출될 때만 로드됩니다. 이는 INSTANCE의 초기화를 트리거하여 동기화된 블록 없이 지연 로딩을 보장합니다.
장점:
단점:
사용 시기: 깨끗하고 유지 관리 가능한 코드로 지연 초기화를 원할 때 내부 정적 클래스 패턴을 사용하세요. 이는 단순성과 스레드 안전성으로 인해 종종 선호되는 선택입니다.
Java에서 스레드로부터 안전한 싱글톤을 구현하는 세 가지 인기 있는 방법을 살펴보았습니다.
각 접근 방식에는 장점이 있으며 다양한 시나리오에 적합합니다. 자신의 프로젝트에서 시도해 보고 어느 것이 가장 적합한지 확인하세요! 선호하는 접근 방식이나 궁금한 점이 있으면 댓글로 알려주세요.
즐거운 코딩하세요! ????
위 내용은 싱글톤이 중단되지 않도록 하세요! Java에서 스레드로부터 안전하게 만드는 방법은 다음과 같습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!