JAVA 가 단일 모드 를 파괴 하 는 방식 및 피 하 는 방법

7232 단어 JAVA단일 모드
단일 모델 은 모두 가 더 이상 익숙 할 수 없 을 것 이다.그 역할 과 실현 방식 은 여러 가지 가 있 으 니 여 기 는 잔소리 하지 않 겠 다.그러나 우리 가 이런 방식 으로 단일 모델 을 실현 할 때 프로그램 에 정말 하나의 사례 만 있 을 까?
      똑똑 한 너 는 이런 질문 을 보고 답 이 NO 라 는 것 을 알 아 맞 혔 을 것 이다.여기 서 필 자 는 뜸 을 들 이지 않 고 단도직입적으로 말 하 자!실제로 일부 장면 에서 프로그램 처리 가 부당 하면 단일 모델 을 무정 하 게 파괴 하여 프로그램 에 여러 개의 인 스 턴 스 대상 이 나타 날 수 있다.
      다음은 필자 가 이미 알 고 있 는 세 가지 사례 모델 을 파괴 하 는 방식 과 피 하 는 방법 을 소개 한다.
1.단일 모델 에 대한 파 괴 를 반사 한다.
      우 리 는 먼저 하나의 예 를 통 해 직관 적 으로 느껴 보 자.
    (1)사례
  DCL 에서 실 현 된 단일 모드:

public class Singleton{
  private static volatile Singleton mInstance;
  private Singleton(){}
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}
테스트 코드:

public class SingletonDemo {

  public static void main(String[] args){
    Singleton singleton = Singleton.getInstance();
    try {
      Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
      constructor.setAccessible(true);
      Singleton reflectSingleton = constructor.newInstance();
      System.out.println(reflectSingleton == singleton);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
실행 결과:
false
      실행 결 과 는 반사 적 인 방식 으로 이 종 류 를 다른 경로 로 만 들 었 기 때문에 프로그램 에 하나의 사례 만 존재 하 는 것 이 아니 라 는 것 을 설명 한다.
    (2)해결 방안
      그 사상 은 하나의 전역 변 수 를 사용 하여 이미 실례 화 되 었 는 지 여 부 를 표시 하 는 것 이다.만약 에 이미 실례 화 되 었 다 면 두 번 째 실례 화 될 때 이상 을 던 지 는 것 이다.구현 코드 는 다음 과 같 습 니 다:

public class Singleton{
  private static volatile Singleton mInstance;
  private static volatile boolean mIsInstantiated = false;
  private Singleton(){
    if (mIsInstantiated){
      throw new RuntimeException("Has been instantiated, can not do it again!");
    }
    mIsInstantiated = true;
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}
실행 결과:

2.clone()의 단일 모드 파괴
       하나의 예 를 들 어 clone()을 허용 해 야 할 때 잘못 처리 하면 프로그램 에 하나의 인 스 턴 스 만 나타 날 수 있 습 니 다.
    (1)사례
  Cloneable 인터페이스 단일 클래스 구현:

public class Singleton implements Cloneable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
    // TODO Auto-generated method stub
    return super.clone();
  }
}
테스트 코드:

public class SingletonDemo {

  public static void main(String[] args){
    try {
      Singleton singleton = Singleton.getInstance();
      Singleton cloneSingleton;
      cloneSingleton = (Singleton) Singleton.getInstance().clone();
      System.out.println(cloneSingleton == singleton);
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
  }
}
실행 결과:
false
  (2)해결 방안:
     해결 사상 은 clone()방법 을 다시 쓰 고 clone()을 바 꿀 때 이미 인 스 턴 스 된 대상 으로 돌아 가 는 것 이다.

public class Singleton implements Cloneable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
    return mInstance;
  }
}
실행 결과:
true
3.단일 모델 에 대한 직렬 화 파괴
   직렬 화/반 직렬 화 를 사용 할 때 도 새로운 인 스 턴 스 대상 이 발생 하 는 경우 가 있다.
  (1)사례
      직렬 화 인 터 페 이 스 를 실현 한 단일 클래스:

public class Singleton implements Serializable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}
테스트 코드:

public class SingletonDemo {

  public static void main(String[] args){
    try {
      Singleton singleton = Singleton.getInstance();
      FileOutputStream fos = new FileOutputStream("singleton.txt");
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(singleton);
      oos.close();
      fos.close();

      FileInputStream fis = new FileInputStream("singleton.txt");
      ObjectInputStream ois = new ObjectInputStream(fis);
      Singleton serializedSingleton = (Singleton) ois.readObject();
      fis.close();
      ois.close();
      System.out.println(serializedSingleton==singleton);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }
}
     실행 결과:
false
    (2)해결 방안
    역 직렬 화 시 리 셋 방법 readResolve()에서 단일 대상 을 되 돌려 줍 니 다.

public class Singleton implements Serializable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }

  protected Object readResolve() throws ObjectStreamException{
    return mInstance;
  }
}
결과:
true
       이상 은 필자 가 현재 알 고 있 는 세 가지 사례 모델 을 파괴 할 수 있 는 장면 과 대응 하 는 해결 방법 이다.독자 가 다른 장면 이 있다 는 것 을 알 면 반드시 공유 해 야 한다.바로'독 락 락 은 대중 락 보다 못 하 다'는 것 이다!!
       단 례 모델 은 디자인 모델 중 가장 간단 한 것 으로 보이 지만'참 새 는 작 지만 오장 이 모두 갖 추어 져 있다'.그 중에서 많은 세부 사항 은 깊이 연구 할 만 한 것 이다.본 편 에서 소개 한 이 몇 가지 장면 도 줄 거 리 를 소 개 했 을 뿐 많은 세부 사항 은 독자 스스로 실험 하고 퇴고 해 야 한다.예 를 들 어 매 거 진 방식 으로 단일 모델 을 실현 하면 상기 문제 가 존재 하지 않 고 다른 실현 방식 은 모두 상기 문제 가 존재 하 는 것 같다.
       후기
       본 편 은 다음 과 같은 자 료 를 표절 하 였 다.
이상 은 JAVA 가 단일 모델 을 파괴 하 는 방식 과 피 하 는 방법 에 대한 상세 한 내용 입 니 다.JAVA 단일 모델 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!

좋은 웹페이지 즐겨찾기