1. 배고픈 중국식 싱글톤
다음과 같이 코드 코드를 복사합니다.
공개 클래스 싱글턴 {
private final static 싱글턴 INSTANCE = new 싱글턴();
개인 싱글턴() { }
공개 정적 싱글턴 getInstance() {
인스턴스를 반환합니다.
}
}
2. 내부 수업의 도움으로
getInstance() 메서드가 처음으로 호출될 때만 내부 클래스 SingletonHolder가 로드(지연 구현)되도록 Java 메커니즘이 규정하고 해당 로드 프로세스가 스레드로부터 안전하기 때문에 이는 게으른 싱글톤입니다. 인스턴스는 내부 클래스가 로드될 때 한 번 인스턴스화됩니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 싱글턴 {
개인 싱글턴() { }
개인 정적 클래스 SingletonHolder {
private final static 싱글턴 INSTANCE = new 싱글턴();
}
공개 정적 싱글턴 getInstance() {
SingletonHolder.INSTANCE를 반환합니다.
}
}
3. 일반 잠금 솔루션
다음과 같이 코드 코드를 복사합니다.
공개 클래스 싱글턴 {
개인 정적 싱글턴 인스턴스 = null;
개인 싱글턴() { }
공개 정적 동기화 싱글톤 getInstance() {
if(인스턴스 == null) {
인스턴스 = 새로운 싱글턴();
}
반환 인스턴스;
}
}
스레드 안전 문제는 해결되었지만 getInstance를 호출하는 모든 스레드는 잠겨야 합니다. getInstance가 처음 호출될 때만 잠그고 싶습니다. 아래의 이중 감지 솔루션을 참조하세요.
4. 이중 감지가 가능하지만 작성 방법에 주의하세요.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 싱글턴 {
개인 정적 싱글턴 인스턴스 = null;
개인 싱글턴() { }
공개 정적 싱글턴 getInstance() {
if(인스턴스 == null) {
synchronzied(Singleton.class) {
싱글톤 온도 = 인스턴스;
if(온도 == null) {
temp = 새로운 싱글톤();
인스턴스=임시
}
}
}
반환 인스턴스;
}
}
명령어 재정렬 문제로 인해 다음과 같이 직접 작성할 수 없습니다.
공개 클래스 싱글턴 {
개인 정적 싱글턴 인스턴스 = null;
개인 싱글턴() { }
공개 정적 싱글턴 getInstance() {
if(인스턴스 == null) {
synchronzied(Singleton.class) {
if(인스턴스 == null) {
인스턴스 = 새로운 싱글턴();
}
}
}
반환 인스턴스;
}
}
그러나 인스턴스 변수가 휘발성으로 수정되면 문제가 없습니다. 인스턴스 = new Singleton();의 해당 명령어도 스레드 순서가 변경되지 않습니다. 안전한:
공개 클래스 싱글턴 {
개인용 정적 휘발성 싱글톤 인스턴스 = null;
개인 싱글턴() { }
공개 정적 싱글턴 getInstance() {
if(인스턴스 == null) {
synchronzied(Singleton.class) {
if(인스턴스 == null) {
인스턴스 = 새로운 싱글턴();
}
}
}
반환 인스턴스;
}
}