여러 인스턴스를 생성하는 대신 특정 클래스의 인스턴스가 하나만 프로그램에 존재하도록 하여 효율성을 향상시킵니다.
단일 관심 모드에서는 일반적으로 인스턴스 개체를 얻기 위해 하나의 getInstance() 메서드만 제공되며, 다른 인스턴스 개체의 인스턴스화를 방지하기 위한 목적으로 setInstance() 메서드가 제공되지 않습니다.
싱글턴 모드에는 두 가지 모드가 있습니다. 하나는 배고픈 모드이고 다른 하나는 게으른 모드입니다.
Hungry Han 모드는 클래스가 로드되는 즉시 인스턴스화되고 이후 사용 시에는 하나의 인스턴스만 나타납니다.
package thread.example; //饿汉模式 public class HungrySingle { //在类加载的时候就实例化了,类加载只有一次,所以值实例化出了一份该实例对象 private static HungrySingle instance = new HungrySingle(); public static HungrySingle getInstance() { return instance; } }
클래스가 로드될 때 이미 인스턴스화되었으므로 인스턴스화에는 인스턴스화 수정 작업이 포함되지 않고 읽기 작업만 수행됩니다. . 다중 스레드 상황에서는 스레드로부터 안전합니다.
은 클래스가 로드될 때 직접 인스턴스화되지 않고 지정된 인스턴스 메서드가 호출될 때 인스턴스화되므로 인스턴스화하고 싶지 않습니다. 일반적으로 말하면 Hungry Man 모드보다 더 효율적입니다.
package thread.example; //单线程的懒汉模式 public class LazySingle { private static LazySingle instance = null; //只有在调用该方法的时候才实例化 public static LazySingle getInstance() { if(instance == null) { instance = new LazySingle(); } return instance; } }
(1) 멀티 스레드 상황에서 레이지 모드가 안전하지 않은 이유
멀티 스레드 상황에서 두 스레드 모두 인스턴스=null을 얻을 가능성이 있습니다. 이는 스레드 1이 주 메모리의 인스턴스를 수정하기 전에 자신의 카운티에서 인스턴스를 수정하는 경우 스레드 2도 이때 인스턴스 개체를 인스턴스화하기 때문입니다. , 더 이상 싱글톤 모드가 아닙니다. 이 문제의 주요 원인은 인스턴스를 수정하고 원자성을 잃는 것과 관련이 있다는 것입니다. 원자성을 보장하기 위해 우리는 스레드 안전성을 달성하기 위해 잠금을 생각했습니다.
(2) 솔루션 코드 예
버전 1
package thread.example; //多线程安全下的懒汉模式 public class LazySingle { private LazySingle() { } private static LazySingle instance = null; //只有在调用该方法的时候才实例化 public static synchronized LazySingle getInstance() { if (instance == null) { instance = new LazySingle(); } return instance; } }
버전 1의 코드는 스레드 안전성을 보장하지만 메서드를 호출할 때마다 잠금 및 잠금 해제 문제가 여전히 발생하므로 추가 최적화를 위해 잠금을 줄일 수 있습니다. 잠금을 추가한 후에는 높은 동시성이 더 이상 가능하지 않지만 여전히 효율성을 향상시키고 싶기 때문에 세분성은 효율성을 향상시키는 데 사용됩니다.
버전 2
Double if 판단 잠금으로 효율성이 향상
package thread.example; public class SecurityLazyModle { private LazySingle() { } private static volatile SecurityLazyModle instance = null;//保证内存可见性,防止编译器过度优化(指令重排序) public static SecurityLazyModle getInstance() { if(instance == null) { synchronized (SecurityLazyModle.class) { if(instance == null) { instance = new SecurityLazyModle(); } } } return instance; } }
버전 2에 대한 설명
if의 첫 번째 레이어는 인스턴스가 생성되었는지 확인하는 것이고, 동기화의 두 번째 레이어는 현재 if를 입력하도록 하는 것입니다. 스레드는 잠금을 얻기 위해 경쟁합니다. 잠금을 획득한 스레드는 if의 세 번째 계층에 들어갈 때 비어 있지 않은지 확인하고, 개체를 인스턴스화한 다음 잠금이 해제됩니다. 인스턴스는 더 이상 비어 있지 않으며 후속 스레드는 if의 세 번째 계층에서 차단됩니다. 나중에 getInstance() 메서드에 액세스하면 인스턴스가 더 이상 비어 있지 않으므로 잠금을 확보할 필요가 없습니다. 잠금을 놓고 경쟁하는 데에도 많은 시간이 소요되기 때문입니다. 이러한 방식으로 처리함으로써 스레드 안전성이 보장되고 효율성이 향상됩니다.
여기서 휘발성을 사용하는 목적은 컴파일러 최적화로 인한 명령어 재정렬을 방지하는 것입니다. 2. 객체 인스턴스화
위 내용은 Java 싱글톤 모드에서 Hungry Man 및 Lazy Man 패턴을 구현하는 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!