Android 디자인 모드 검토 - 단일 모드

4126 단어
핵심 원칙: 구조 함수를 사유화하고 정적 내부 방법을 통해 유일한 실례를 얻는다.
단일 모델의 정의: 특정한 종류가 하나의 실례만 있는 것을 확보하고 여러 개의 대상이 발생하여 과도한 자원을 소모하지 않도록 한다.다음은 몇 가지 흔히 볼 수 있는 단례 모델을 실현하는 방법을 소개한다.
굶주린 사람 모드는 정적 클래스를 설명할 때 대상이 존재하고 초기화됩니다.
public class Singleton{
  private  static Singleton mInstance = new Singleton();// static, .
  public static Singleton getInstance() {// 
    return mInstance;
  }
  private Singleton() {// private 
  }
}

장점: 비교적 간단하게 쓰고 라인이 안전합니다.단점: 자원을 소모합니다. 설령 당신이 이 예를 사용하지 않더라도 정적 저장 공간에서 이 실례에 공간을 분배할 수 있기 때문입니다.
게으름뱅이 모드. 게으름 불러오는 모드입니다.사용할 때 불러오고, 사용하지 않을 때 공간을 차지하지 않습니다
public class Singleton{
private static Singleton mInstance;
public static synchronized Singleton getInstance() {// synchronized, , .
  if(mInstance == null) {
     mInstance =new Singleton();
  }
  return mInstance;
}
}

장점: 다선정이 안전하고 굶주린 사람 모드보다 좋으며 필요할 때만 실례화된 Singleton 대상입니다.단점: getInstance를 호출할 때synchronized 자물쇠가 추가되었기 때문에 다른 라인이 호출될 때 기다려야 하기 때문에 불필요한 자원 비용이 발생합니다.
DCL 모드 Double Check Lock 모드로 초기화할 수 있으며 getInstance 방법으로 동기화할 필요가 없습니다.
public class Singleton{
    private static volatile Singleton mInstance;// volatile 
    public static Singleton getInstance() {
       if(mInstance == null) {// 
          synchronized(Singleton.class){// Singleton.class 
          if(mInstance == null) {// 
                mInstance =new Singleton();
           }
      }
   }
    return mInstance;
  }

}

volatile 이 키워드를 사용해야 하는 이유 위 코드에서 mInstance = new Singleton ();사실은 원자 조작이 아니다. 컴파일한 후 대체적으로 다음과 같은 3가지 일을 했다. 1) 싱leton에 메모리 공간 분배 2) 구조 함수, 구성원 변수 초기화 3) mInstance 대상은 싱leton이 분배한 메모리 공간을 가리킨다
문제는 자바 컴파일러가 프로세서의 순서를 어지럽히는 것을 허용하기 때문에 위의 것은 1->3->2일 수 있다. 예를 들어 두 개의 스레드 A, B는 각각 getInstance 정적 함수를 호출했고 A는 1->3->2의 순서를 실행했다. 3을 실행할 때 B스레드 콜 getInstance 정적 함수에서 얻은 mInstance는 비어 있지 않다. 바로 되돌아간다. 이때 B스레드는 이 실례를 직접 사용하면 문제가 발생한다. 왜냐하면 이 실례가 초기화되지 않았기 때문이다.이렇게 호출하면 오류가 발생합니다.위의 원인에 근거하여 JDK1.5 다음에volatile이라는 키워드를 도입하여 컴파일러가 매번 1->2->3 순서로 실행하도록 했습니다. 이렇게 하면 여러 라인의 문제가 없고 라인도 안전합니다.
DCL의 장점: 자원의 이용률이 높고 사용할 때만 대응하는 공간을 초기화한다.그리고 효율적으로 라인 동기화를 실현한다.DCL의 단점:volatile 키워드를 사용하여 처음 불러오는 속도가 조금 느립니다.
정적 내부 클래스는 자바 가상 머신 로드 클래스의 특성을 이용하여 라인 안전, 자원 소모 등 문제를 해결했다.
  public  class Singleton {

       private Singleton() {
        }

        public static Singleton getInstance() {
            return SingletonHolder.mInstance;
        }

        public static class SingletonHolder {
            private static final Singleton mInstance = new Singleton()
        }

 }

이러한 방식은 JVM의 클래스 로딩 방식(가상 기회는 하나의 클래스의 초기화가 다중 스레드 환경에서 정확하게 잠기고 동기화됨)을 통해 다중 스레드의 동시 접근의 정확성을 확보한다. 정적 내부 클래스의 로딩 특성 때문에 사용할 때 로딩을 하기 때문에 로딩을 게을리 하는 모델을 실현했다.
장점: 스레드 보안, 게으름 피우기 단점: 자바 가상 머신에 의존해야 함
매거
public enum Singleton{
INSTANCE;
}

장점: 단일 요소 매거는 다중 루틴 동기화 문제를 피할 수 있을 뿐만 아니라 반서열화할 때 새로운 대상을 다시 만드는 것을 방지할 수 있다
Android의 단일 예제 사용
 
public final class InputMethodManager {
static InputMethodManager sInstance;
...
   public static InputMethodManager getInstance() {
        synchronized (InputMethodManager.class) {
            if (sInstance == null) {
                IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
                IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
                sInstance = new InputMethodManager(service, Looper.getMainLooper());
            }
            return sInstance;
        }
    }
....

예를 들어 InputMethod Manager는 게으름 모드를 이용했지만, 라인이 안전하지 않습니다.volatile 키워드 없음
public static synchronized CalendarDatabaseHelper getInstance(Contextcontext)  
{  
    if (sSingleton == null)  
    {  
       sSingleton = newCalendarDatabaseHelper(context);  
    }  
        return sSingleton;  
}  

게으름뱅이 모드의 Calendar DatabaseHelper 클래스를 사용하여Calendar 데이터베이스에 조작
결론: 1) 단례 모델을 실현하는 것은 3단계로 나뉜다. 구조기의 사유화, 사유 정적 변수를 성명하고 정적 획득 실례를 제공하는 방법이다.2) 단일 스레드 추천 게으름 로드 모드인 경우, 다중 스레드 추천 정적 내부 클래스의 경우 단일 사례 3) 데이터베이스 조작, 자원 접근, IO 조작 등 단일 사례 모델로 처리하는 것이 좋다

좋은 웹페이지 즐겨찾기