안드로이드 디자인 모드 (1) 단일 모드 설명
4384 단어 안드로이드 디자인 모드
정의
어떤 종류가 하나의 실례만 있을 수 있도록 확보하고, 자체적으로 실례화하여 전체 시스템에 이 실례를 제공한다.장면 사용: • 입출력 액세스와 같은 여러 객체에서 너무 많은 리소스가 소모되는 것을 방지할 수 있습니다.• 일부 유형의 대상은 하나뿐이어야 하며 여러 대상이 논리적 오류나 혼란을 초래할 수 있다.
2. 흔히 볼 수 있는 실현 방식
다음은 단례 모델에서 흔히 볼 수 있는 두 가지 실현 방식인 굶주림 모델과 이중 잠금 모델이다
• 굶주림 모드public class Singleton {
private static Singleton mInstance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return mInstance;
}
}
굶주림식은 가장 간단한 실현 방식이다. 이런 실현 방식은 초기화할 때 단례로 사용해야 하는 상황에 적합하다.간단하고 거칠어서, 네가 이 실례를 필요로 하든지 말든지, 먼저 너에게 창설해 줄게.만약 단일 대상의 초기화가 매우 빠르고 메모리를 매우 적게 차지할 때 이런 방식이 비교적 적합하다면, 응용 프로그램이 시작될 때 직접 불러오고 초기화할 수 있다.그러나 만약에 한 사례의 초기화 작업이 비교적 오래 걸리고 응용 프로그램이 시작 속도에 대한 요구가 있거나 한 사례의 메모리 사용이 비교적 크거나 한 사례가 특정한 장면에서만 사용될 수 있고 일반적인 상황에서 사용하지 않을 때 굶주린 사례의 모델을 사용하는 것은 적합하지 않다. 이럴 때 게으름뱅이 방식으로 필요에 따라 한 사례를 지연시켜야 한다.
• 이중 잠금 모드(DCL 구현)public class Singleton {
private static Singleton mInstance = null;
private Singleton() { }
public static Singleton getInstance() {
if (mInstance == null) {
synchronized (Singleton.class) {
if (mInstance == null) {
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
또 하나는 게으름뱅이 모드이다. 사용할 때 getInstance () 방법에서 실례적인 창설 (new) 을 완성하는 동시에 이 방법에synchronized 키워드를 추가하면 다중 스레드 상황에서 단례가 유일하다는 것을 확보할 수 있지만 게으름뱅이 모드가 getInstance 방법을 호출할 때마다synchronized의 존재로 인해 동기화를 해야 하기 때문에 불필요한 자원 비용을 초래한다.그래서 이중 잠금 모드의 실현 방식이 생겼다.이렇게 하면 굶주린 사람의 단점을 피할 수 있을 뿐만 아니라 게으른 사람의 부족도 해결할 수 있다.첫 번째 진정으로 필요할 때만 단례를 만들 수 있도록 하세요.
DCL과 같은 모델의 하이라이트는 getInstance() 방법에서 singleton에 대해 두 차례 빈 여부를 판단한 데 있다.• 1층 판단은 불필요한 동기화를 피하기 위한 것이고 2층 판단은null의 상황에서 실례를 만들기 위한 것이다.
구체적으로 살펴보겠습니다.
스레드 A가 singleton = new Singleton ()에 실행되었다고 가정합니다.문장, 여기는 코드로 보이지만 원자 조작이 아니다. 이 코드는 최종적으로 여러 개의 어셈블리 명령으로 컴파일되고 대체적으로 세 가지 일을 할 수 있다.
Singleton의 인스턴스에 메모리 할당Singleton () 의 구조 함수를 호출하여 구성원 필드를 초기화하기;
singleton 대상을 분배된 메모리 공간으로 가리키기(즉singleton이 비어 있지 않음);
그러나 자바 컴파일러는 프로세서가 jdk1.5 이전에 JMM(Java Memory Model:java 메모리 모델)에서Cache, 레지스터, 메인 메모리에 대한 리셋 순서에 따라 위의 b단계 c의 실행 순서는 보장되지 않았다.즉, 집행 순서는 1-2-3일 수도 있고 1-3-2일 수도 있다. 후자의 지향 순서이고 마침 3이 집행되고 2가 집행되지 않았을 때 라인 B로 전환된다. 이때singleton이 라인 A에서 3단계를 집행했기 때문에 이미 비어 있기 때문에 라인 B는 직접singleton을 가져가서 다시 사용할 때 오류가 발생한다.이것이 바로 DCL의 실효 문제입니다.
하지만 JDK에서는5 이후 공식적으로volatile 키워드를 제시하여singleton이 정의한 코드를 다음과 같이 바꾸었다.private volatile static Singleton singleton; // volatile
이렇게 하면 DCL의 실효 문제를 해결할 수 있다.volatile의 역할은 다음과 같습니다.
다음은 단례 모델에서 흔히 볼 수 있는 두 가지 실현 방식인 굶주림 모델과 이중 잠금 모델이다
• 굶주림 모드
public class Singleton {
private static Singleton mInstance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return mInstance;
}
}
굶주림식은 가장 간단한 실현 방식이다. 이런 실현 방식은 초기화할 때 단례로 사용해야 하는 상황에 적합하다.간단하고 거칠어서, 네가 이 실례를 필요로 하든지 말든지, 먼저 너에게 창설해 줄게.만약 단일 대상의 초기화가 매우 빠르고 메모리를 매우 적게 차지할 때 이런 방식이 비교적 적합하다면, 응용 프로그램이 시작될 때 직접 불러오고 초기화할 수 있다.그러나 만약에 한 사례의 초기화 작업이 비교적 오래 걸리고 응용 프로그램이 시작 속도에 대한 요구가 있거나 한 사례의 메모리 사용이 비교적 크거나 한 사례가 특정한 장면에서만 사용될 수 있고 일반적인 상황에서 사용하지 않을 때 굶주린 사례의 모델을 사용하는 것은 적합하지 않다. 이럴 때 게으름뱅이 방식으로 필요에 따라 한 사례를 지연시켜야 한다.
• 이중 잠금 모드(DCL 구현)
public class Singleton {
private static Singleton mInstance = null;
private Singleton() { }
public static Singleton getInstance() {
if (mInstance == null) {
synchronized (Singleton.class) {
if (mInstance == null) {
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
또 하나는 게으름뱅이 모드이다. 사용할 때 getInstance () 방법에서 실례적인 창설 (new) 을 완성하는 동시에 이 방법에synchronized 키워드를 추가하면 다중 스레드 상황에서 단례가 유일하다는 것을 확보할 수 있지만 게으름뱅이 모드가 getInstance 방법을 호출할 때마다synchronized의 존재로 인해 동기화를 해야 하기 때문에 불필요한 자원 비용을 초래한다.그래서 이중 잠금 모드의 실현 방식이 생겼다.이렇게 하면 굶주린 사람의 단점을 피할 수 있을 뿐만 아니라 게으른 사람의 부족도 해결할 수 있다.첫 번째 진정으로 필요할 때만 단례를 만들 수 있도록 하세요.
DCL과 같은 모델의 하이라이트는 getInstance() 방법에서 singleton에 대해 두 차례 빈 여부를 판단한 데 있다.• 1층 판단은 불필요한 동기화를 피하기 위한 것이고 2층 판단은null의 상황에서 실례를 만들기 위한 것이다.
구체적으로 살펴보겠습니다.
스레드 A가 singleton = new Singleton ()에 실행되었다고 가정합니다.문장, 여기는 코드로 보이지만 원자 조작이 아니다. 이 코드는 최종적으로 여러 개의 어셈블리 명령으로 컴파일되고 대체적으로 세 가지 일을 할 수 있다.
Singleton의 인스턴스에 메모리 할당Singleton () 의 구조 함수를 호출하여 구성원 필드를 초기화하기;
singleton 대상을 분배된 메모리 공간으로 가리키기(즉singleton이 비어 있지 않음);
그러나 자바 컴파일러는 프로세서가 jdk1.5 이전에 JMM(Java Memory Model:java 메모리 모델)에서Cache, 레지스터, 메인 메모리에 대한 리셋 순서에 따라 위의 b단계 c의 실행 순서는 보장되지 않았다.즉, 집행 순서는 1-2-3일 수도 있고 1-3-2일 수도 있다. 후자의 지향 순서이고 마침 3이 집행되고 2가 집행되지 않았을 때 라인 B로 전환된다. 이때singleton이 라인 A에서 3단계를 집행했기 때문에 이미 비어 있기 때문에 라인 B는 직접singleton을 가져가서 다시 사용할 때 오류가 발생한다.이것이 바로 DCL의 실효 문제입니다.
하지만 JDK에서는5 이후 공식적으로volatile 키워드를 제시하여singleton이 정의한 코드를 다음과 같이 바꾸었다.
private volatile static Singleton singleton; // volatile
이렇게 하면 DCL의 실효 문제를 해결할 수 있다.volatile의 역할은 다음과 같습니다.
더 많은 것은 몇몇 복잡한 장면에서 상술한 두 가지 방식 모두 다소 결함이 존재한다.따라서 다음과 같은 두 가지 단일 모델의 실현 방식이 생겼다.
• 정적 내부 클래스
public class Singleton {
private Singleton(){ }
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
/**
*
*/
private static SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}
Singleton 클래스를 처음 불러올 때 sInstance를 초기화하지 않습니다. Singleton의 getInstance 방법을 처음 호출할 때만 sInstance가 초기화됩니다.따라서 getInstance 방법을 처음 호출하면 가상 기기에singletonHolder류를 불러올 수 있다. 이런 방식은 라인의 안전을 확보할 수 있을 뿐만 아니라 단일 대상의 유일성을 확보할 수 있을 뿐만 아니라 단일 사례의 실례화도 지연시킬 수 있기 때문에 이것은 추천하는 단일 모델의 실현 방식이다.
일일이 열거하다
publicenum Singleton {
// , Singleton
INSTANCE;
public void doSomething(){
//do something
}
}
매거 원소를 정의하는데 그가 단례이다.이것은 하나의 예를 실현하는 가장 간단하고 가장 실속 있는 방식이라고 할 수 있다.반서열화 과정에서 단례가 만들어지는 것을 효과적으로 피하고 단례를 유일하지 않게 할 수 있다.기본 매거 실례의 창설은 라인 안전(매거 클래스를 만드는 단례는 JVM 차원에서도 라인 안전을 보장할 수 있다)이기 때문에 라인 안전 문제를 걱정할 필요가 없기 때문에 이론적으로 매거 클래스로 단례 모델을 실현하는 것이 가장 간단한 방식이다.
매거진이 코드를 더욱 쉽게 읽을 수 있고 안전하게 할 수 있다는 것은 부인할 수 없다. 많은 고전적인 자바 책에서 인트 상수 대신 매거진을 추천하지만 안드로이드 홈페이지에서는 매거진을 권장하지 않는다. 메모리를 많이 차지하기 때문이다.특히 대형 앱에서는 안 쓸 수 있으면 안 쓴다.실행 속도와 파일 부피를 크게 늘리기 때문이다.이것은 성능 최적화에서 OOM을 줄이는 한 방면이기도 하다.
3. 총결산
단례 모델은 운용 빈도가 매우 높은 모델이지만 클라이언트가 통상적으로 높은 합병 상황이 없기 때문에 어떤 실현 방식을 선택해야 큰 영향을 주지 않는다.그럼에도 불구하고 효율적인 차원에서 DCL, 정적 내부 클래스의 형식을 추천합니다.
단점:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
안드로이드 디자인 모드 (1) 단일 모드 설명이런 실현 방식은 초기화할 때 단례로 사용해야 하는 상황에 적합하다.간단하고 거칠어서, 네가 이 실례를 필요로 하든지 말든지, 먼저 너에게 창설해 줄게.만약 단일 대상의 초기화가 매우 빠르고 메모리를 매우 적게 차지...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.