3. 싱글 톤 디자인 패턴

디자인 패턴은 누구나 알고 있고, 가장 많이들은 패턴은 싱글 톤 디자인 패턴이어야한다고 생각합니다.이 패턴은 또한 개발에서 가장 많이 사용되는 디자인 패턴입니다. 여러 디자인 패턴을 작성하는 사람들이 많을 수 있으므로 무엇을 알고 계십니까? 디자인 패턴? 싱글 톤 디자인 패턴이있는 이유, 즉 그 역할은 무엇입니까? 싱글 톤 모드를 작성하는 방법은 무엇입니까? 이러한 질문에 대해서는 일부 아동용 신발이 잘 대답하지 못할 수 있습니다. 오늘 여러분과 함께 싱글 톤 디자인 패턴을 자세히 공부하는 것은 괜찮습니다.이 기사를 통해 싱글 톤 디자인 패턴을 자세히 이해하게 될 것입니다. 오류가 있으시면 비판과 정정을하실 수 있으며, 질문이 있으시면 메시지를 남겨주세요.

이 블로그를 통해 다음과 같은 내용을 배울 수 있습니다.
① 디자인 패턴이란 무엇입니까
② 왜 Singleton 디자인 패턴이 유용하고 문제를 해결
하는지 ③ 단일 케이스를 달성하는 방법, 즉 디자인이 무엇인지
④ 싱글 톤
패턴 을 쓰는 방법은 무엇인가 ⑤ 싱글 톤 패턴 인터뷰에서 주목해야 할 사항

1. 디자인 패턴이란?

  먼저 첫 번째 질문부터 보겠습니다 디자인 패턴이란? Baidu Encyclopedia의 정의는 다음과 같습니다. 디자인 패턴은 반복적으로 사용되는 집합으로, 대부분의 사람들은 코드 디자인 경험을 요약하여 알고 분류하고 분류합니다. (바이두 백과 사전)
사실 디자인 패턴은 사람들의 실천의 산물입니다. 초기 개발 과정에서 많은 사람들이 반복되는 코드 작성을 발견했습니다. 계속해서 요약하고 추출한 개발자들은 마침내 모두에게 인정 받아 디자인이 나왔습니다. 패턴은 실제로 디자인 패턴의 종류는 약 23 가지로 나눌 수 있는데, 오늘은이 디자인 패턴이 가장 많이 사용되는 디자인 패턴이기 때문에 모두와 함께 싱글 톤 디자인 패턴을 주로 공부하겠습니다. 향후 기사에서는 다른 모드에 대해 논의 할 것입니다.

2. 싱글 톤 디자인 패턴이있는 이유는 무엇입니까?

우리 모두는 싱글 톤 패턴이 개발에서 가장 많이 사용되는 디자인 패턴이라는 것을 알고 있는데, 싱글 톤 디자인 패턴이있는 이유는 무엇입니까? 이 문제에 대해서는 싱글 톤을 쓸 수있는 많은 사람들이이 질문을 할 것이라고 믿습니다. 먼저 싱글 톤의 사용에 대해 이야기하고 예를 들어 보면 모든 사람들이 싱글 톤이있는 이유를 이해할 것입니다. 싱글 톤 모드는 주로 여러 인스턴스 생성으로 인한 리소스 낭비를 방지하기위한 것이며, 여러 인스턴스는 여러 호출로 인해 결과에 오류가 발생할 수 있습니다. 싱글 톤 모드를 사용하면 전체 애플리케이션에 하나의 인스턴스 만있을 수 있습니다. 이름에서 우리는 소위 싱글 톤이 단일 인스턴스임을 알 수 있습니다. 즉, 해결할 수있는 문제는 메모리, 일반적으로 사용되는 일부 도구 클래스, 스레드 풀 및 캐시에서 클래스 개체의 고유성을 보장 할 수 있다는 것입니다. , 데이터베이스, 계정 로그인 시스템, 구성 파일 및 기타 프로그램을 사용하면 하나의 개체 만 생성 할 수 있습니다. 한편으로 여러 개체를 생성하면 프로그램 오류가 발생할 수있는 반면, 여러 개체를 생성하면 리소스가 낭비 될 수 있습니다. 이를 바탕으로 싱글 톤 디자인 패턴이 탄생 한 이유는 싱글 톤을 사용하면 전체 애플리케이션에 하나의 인스턴스 만 있음을 보장 할 수 있기 때문입니다. 이걸 보면 약간 혼란 스러울 수 있습니다. 중요하지 않습니다. 예를 들어 보겠습니다. 싱글 톤이있는 이유는 매우 분명합니다.

이러한 요구 사항이있는 경우 구성 파일의 정보를 공유하는 클래스 A와 클래스 B가 있습니다.이 구성 파일에는 아래 그림과 같이 많은 데이터가 있습니다.

여기에 사진 설명 삽입

위의 그림과 같이 ConfigFile 클래스에는 공유 데이터 Num1, Num2, Num3 등이 있습니다. 클래스 A의 ConfigFile에서 데이터를 수정하면 클래스 A에 다음 코드가 있어야합니다.

ConfigFile configFile=new ConfigFile();
configFile. Num1=2;

이때 configFile의 Num1 = 2이지만 여기에 새로운 ConfigFile이 객체라는 점에 유의하십시오. 위의 작업 후 클래스 B에서 다음 작업을 상상해보십시오.

ConfigFile configFile=new ConfigFile();
System. out.println("configFile.Num1=" +configFile.Num1);

즉, 직접 new ConfigFile (); 그런 다음 Num1을 인쇄합니다. 이때 인쇄 된 데이터에 대해 생각해보십시오. 나는 그것이 다음과 같은 결과를 인쇄한다는 것을 알아야한다고 생각합니다 : configFile.Num1 = 1; 즉, 각 호출이 ConfigFile 객체를 생성하기 때문에 클래스 A의 수정은 실제로 ConfigFile을 변경하지 않습니다. 값, 클래스 A에서 생성 된 객체의 값만 변경합니다. 이제 A 등급의 데이터를 수정해야하는 경우 B 등급에 알려야합니다. 즉, A 등급과 B 등급에서 작동하는 데이터가 동일한 데이터이고 A 등급이 데이터를 변경하면 B 등급도이 데이터를 가져 오며 A 등급에 해당됩니다. 작업은 수정 된 기준으로 수행되므로 어떻게해야합니까? 이걸 보면 누구나 쉽게 말할 수 있습니다. ConfigFile의 데이터를 정적으로 설정해도 괜찮지 않습니까? 예,이 아이디어를 갖는 것이 좋습니다. 잘못된 것은 없습니다. 그러나 우리 모두는 정적 데이터의 수명주기가 매우 길다는 것을 알고 있습니다 .ConfigFile에 많은 데이터가있는 경우 모든 데이터가 정적으로 설정되면 메모리가 크게 손실됩니다. 따라서 모두 정적으로 설정하는 것이 가능하지만 좋은 해결책은 아닙니다. 그래서 우리는 무엇을해야합니까? 위의 문제를 해결하는 것은 어렵지 않습니다. 객체가 고유하다는 것을 보장 할 수있는 한 위의 문제를 해결할 수 있습니다. 그러면 문제는 객체의 고유성을 어떻게 보장 할 것인가? 따라서 싱글 톤 디자인 패턴을 사용해야합니다.

3. 싱글 톤 모드의 디자인 아이디어

위에서 언급 한 문제 해결의 핵심은 응용 프로그램에 개체가 하나만 있는지 확인하는 것입니다. 그러면 개체가 하나만 있는지 확인하는 방법은 무엇입니까?
실제로 개체의 고유성을 보장하는 데 세 단계 만 필요합니다.

(1) 다른 프로그램은 새 개체를 사용할 수 없습니다.

new는 새로운 공간을 여는 것이므로 여기에서 데이터를 변경하면 생성 된 객체의 데이터 만 변경되며, 새로운 객체 일 경우 모든 새 객체가 생성되므로 객체의 고유성을 보장 할 수 없습니다.

(2)
다른 프로그램이 새 개체에 허용되지 않기 때문에이 클래스에 개체를 만듭니다 . 따라서 여기에있는 개체는이 클래스에서 새 개체 여야합니다.

(3) 다른 프로그램이 객체를 획득 할 수있는 방법 제공

객체는이 클래스에서 생성되기 때문에 다른 클래스가이 객체를 얻기 위해 메서드를 제공해야합니다.

그렇다면이 세 단계를 코드에서 어떻게 구현할까요? 위의 세 단계를 다음과 같은 코드 설명으로 변환하십시오.

(1)
이 클래스 의 생성자를 민영화합니다. (2) new를 통해이 클래스에이 클래스의 객체를 만듭니다.
(3)이 클래스에서 생성 된 객체를 반환하는 공용 메서드를 정의합니다.

4. 싱글 톤 모드 작성 방법

3 번의 분석을 통해 싱글 톤으로 해결 된 문제와 그 실현 아이디어를 이해하고 구현 코드를 살펴보면 싱글 톤 패턴의 작성은 5 가지 종류와 5 가지 종류 ① 게으른 사람 ② 배고픈 사람으로 나눌 수 있습니다. 공식 ③ 재확인 잠금 ④ 정적 내부 클래스 ⑤ 열거. 다음으로, 이러한 몇 가지 싱글 톤 디자인 패턴의 코드 구현과 그 장단점을 살펴 보겠습니다.

4.1 배고픈 중국어 싱글 톤 모드 [사용 가능]

public class Singleton {
 
	private static Singleton instance=new Singleton();
	private Singleton(){};
	public static Singleton getInstance(){
		return instance;
	}
}

인터뷰 방법

Singleton instance = Singleton.getInstance();

得到这个实例后就可以访问这个类中的方法了。

장점 : 구현을 통해이 메서드의 구현이 비교적 간단하고 클래스가로드 될 때 인스턴스화가 완료되어 스레드 동기화 문제를 피할 수 있음을 알 수 있습니다.

단점 : 클래스가로드 될 때 인스턴스화되기 때문에 Lazy Loading의 효과를 얻지 못합니다. 즉,이 인스턴스를 사용할 수 없지만

또한로드되므로 메모리 낭비가 발생합니다 (하지만이 낭비는 무시할 수 있으므로이 방법도 권장 됨).

4.2 배고픈 중국 스타일의 싱글 톤 모드 변환 [사용 가능]

public class Singleton{

  private static Singleton instance = null;
  
  static {
  	instance = new Singleton();
  }

  private Singleton() {};

  public static Singleton getInstance() {
  	return instance;
  }
}

인터뷰 방법 :

Singleton instance = Singleton.getInstance();

得到这个实例后就可以访问这个类中的方法了。

위의 코드는 2에서 분석 한 3 단계에 따라 구현 된 것을 알 수있다. 쓰기 방식은 클래스 생성시 이미 객체를 인스턴스화했기 때문에 배고픈 스타일이라고한다. 사실 4.2와 4.1은 글쓰기가 조금 다르지만 클래스가 초기화 될 때 객체가 생성되며 장단점은 4.1과 동일하여 하나의 글로 분류 할 수 있습니다.

4.3 싱글 톤 모드의 게으른 스타일 [스레드는 안전하지 않으며 사용할 수 없습니다]

public class Singleton {
 
	private static Singleton instance=null;
	
	private Singleton() {};
	
	public static Singleton getInstance(){
		
		if(instance==null){
			instance=new Singleton();
		}
		return instance;
	}
}

이 메서드는 getInstance 메서드가 호출 될 때 객체를 생성하므로 lazy이고 lazy라고합니다.
위의 두 가지 글쓰기 방식에서 게으른 사람은 실제로 쓰레드 안전 문제를 가지고 있는데, 문제를 뿌리 내리고 싶은 학생들은 어떤 종류의 쓰레드 안전 문제가 있는가? 이 문제의 원인은 무엇입니까? 좋아, 어떤 상황에서이 글이 문제가 될지 이야기 해 봅시다. 실행중인 프로세스에 이러한 상황이있을 수 있습니다. Singleton의 인스턴스를 얻기 위해 getInstance 메서드를 호출하는 여러 스레드가있는 경우 첫 번째 스레드가 다음 경우에 실행될 때 이러한 상황이 발생할 수 있습니다.null)이 문장, 이때 instance는 null에 대한 입력 문장이다. instance = new Singleton ()이 실행되지 않은 경우 (현재 인스턴스는 null 임) 두 번째 스레드도 if (instancenull)이 문은 이전에이 문을 입력 한 스레드가 instance = new Singleton ()을 실행하지 않았기 때문에 두 번째 스레드도 if 문에 들어갔 기 때문에 instance = new Singleton ()을 실행하여 Singleton 객체를 인스턴스화합니다. 또한 Singleton 개체를 인스턴스화합니다. 이로 인해 두 개의 Singleton 개체가 인스턴스화되었습니다. 그래서 싱글 톤 모드의 게으른 사람은 쓰레드 안전성 문제가 있는데 문제가 있기 때문에이 문제를 해결할 방법이있을 수 있는데 어떻게 해결해야할까요? 이런 종류의 문제에 대해 많은 사람들이 잠금을 생각할 수 있으므로 다음과 같은 문구가 나타났습니다.

4.4 Lazy-style thread-safe [스레드 안전성, 낮은 효율성은 권장되지 않음]


public class Singleton {
 
	private static Singleton instance=null;
	
	private Singleton() {};
	
	public static synchronized Singleton getInstance(){
		
		if(instance==null){
			instance=new Singleton();
		}
		return instance;
	}
}

단점 : 효율성이 너무 낮고 각 스레드가 클래스의 인스턴스를 얻으려면 getInstance () 메서드의 실행을 동기화해야합니다. 실제로이 메서드는 인스턴스화 코드를 한 번만 실행하기에 충분하며 나중에이 클래스의 인스턴스를 얻으려면 직접 반환하면됩니다. 동기화 효율성의 방법이 너무 낮아 개선 할 수 없습니다.
4.5 Singleton mode lazy style [스레드가 안전하지 않음, 사용할 수 없음]
위의 결함을 개선하기 위해 일부 사람들은 다음 코드를 생각할 수 있습니다.

public class Singleton7 {
 
	private static Singleton instance=null;
	
	public static Singleton getInstance() {
		if (instance == null) {
			synchronized (Singleton.class) {
				instance = new Singleton();
			}
		}
		return instance;
	}
}

실제로이 쓰기 방법은 4.3과 같이 스레드에 안전하지 않습니다. 스레드가 Singleton을 인스턴스화하지 않은 경우 if (instance == null) 판정 문에 도달하면 다른 스레드가 if 문에 들어갑니다. 잠금이 추가되었지만, 첫 번째 스레드가 instance = new Singleton () 실행을 마치고 잠금을 벗어나면 if 문에 들어가는 다른 스레드도 다른 Singleton 객체를 인스턴스화합니다. 스레드 불안정의 원칙은 4.3과 유사합니다. 따라서 이러한 개선 방법은 불가능하며, 위대한 신들이 단계적으로 탐색 한 후 게으른 이중 확인 잠금을 작성했습니다.

4.6 싱글 톤 모드 지연 이중 확인 잠금 [권장]

public class Singleton {
	/**
	 * 懒汉式变种,属于懒汉式中最好的写法,保证了:延迟加载和线程安全
	 */
	private static Singleton instance=null;
	
	private Singleton() {};
	
	public static Singleton getInstance(){
		 if (instance == null) {  
	          synchronized (Singleton.class) {  
	              if (instance == null) {  
	            	  instance = new Singleton();  
	              }  
	          }  
	      }  
	      return instance;  
	}
}

인터뷰 방법

Singleton instance = Singleton.getInstance();

得到这个实例后就可以访问这个类中的方法了。

Double-Check의 개념은 멀티 스레드 개발자에게 익숙하지 않은데, 코드에서 볼 수 있듯이 스레드 안전성을 보장하기 위해 두 번의 if (instance == null) 검사를 수행했습니다. 이런 식으로 인스턴스화 코드는 한 번만 실행하면되며 나중에 다시 액세스하면 (instance == null)인지 판단하고 인스턴스화 된 객체를 직접 반환합니다.

장점 : 스레드 안전성, 지연 로딩, 더 높은 효율성.

4.7 내부 카테고리 [권장]

public class Singleton{
 
	
	private Singleton() {};
	
	private static class SingletonHolder{
		private static Singleton instance=new Singleton();
	} 
	
	public static Singleton getInstance(){
		return SingletonHolder.instance;
	}
}

인터뷰 방법

Singleton instance = Singleton.getInstance();

得到这个实例后就可以访问这个类中的方法了。

   이 방법은 Hungry Chinese 방법에서 채택한 메커니즘과 유사하지만 다릅니다. 둘 다 클래스 로딩 메커니즘을 사용하여 인스턴스를 초기화 할 때 스레드가 하나만 있는지 확인합니다. 다른

배고픈 중국 스타일의 위치는 Singleton 클래스가로드되는 한 Lazy-Loading의 효과없이 인스턴스화되며 정적 내부 클래스 메서드는 Singleton 클래스가로드 될 때입니다.

즉시 인스턴스화되지는 않지만 인스턴스화가 필요한 경우 getInstance 메서드가 호출되어 SingletonHolder 클래스를로드하여 Singleton의 인스턴스화를 완료합니다.

클래스의 정적 속성은 클래스가 처음로드 될 때만 초기화되므로 여기서 JVM은 스레드의 안전성을 보장하는 데 도움이됩니다. 클래스가 초기화되면 다른 스레드는

액세스 할 수 없습니다.

장점 : 스레드 불안정, 지연로드 및 고효율을 피하십시오.

4.8 열거 [적극 권장]

public enum SingletonEnum {
	
	 instance; 
	 
	 private SingletonEnum() {}
	 
	 public void method(){
	 }
}

인터뷰 방법

SingletonEnum.instance.method();

열거 형 작성이 매우 간단하고 액세스도 매우 간단하다는 것을 알 수 있습니다. 여기서 SingletonEnum.instance 여기의 인스턴스는 SingletonEnum 유형의 참조이므로 얻을 때 열거 형에서 메서드를 호출 할 수 있습니다.

JDK1.5에 추가 된 열거를 사용하여 싱글 톤 모드를 실현합니다. 다중 스레드 동기화 문제를 방지 할 수있을뿐만 아니라 역 직렬화가 새 개체를 다시 만드는 것을 방지 할 수 있습니다. JDK1.5에 열거 형이 추가 되었기 때문에 실제 프로젝트 개발에서는 이런 식으로 작성한 사람이 거의없는 것 같습니다.이 방법도 가장 좋은 방법입니다. JDK가 개발 중 요구 사항을 충족하는 경우 권장됩니다. 이 방법을 사용하십시오.

5. 요약

실제 프로젝트 개발에서는 일반적으로 4.1, 4.6, 4.7, 4.8을 사용하여 가장 좋아하는 글쓰기 방법을 확인합니다. 정상적인 상황에서는 이러한 모드에 문제가 없습니다. 4.6을 사용하도록 강제하기 위해 자주 사용합니다. Android-Universal-Image-Loader 오픈 소스 프로젝트도 4.6을 사용합니다. 실제로 가장 안전한 작성 방법은 열거 형인 4.8입니다. 구현은 매우 간단하고 가장 안전한 것은 완벽하지만 JDK1 만 지원하기 때문일 수 있습니다. 5. 또는 열거가 모든 사람에게 익숙하지 않기 때문에 현재 많은 사람들이 사용하지 않지만 시도해 볼 수 있습니다. 또한 리플렉션 메커니즘을 사용하면 인스턴스의 고유성이 보장되지 않을 수 있지만 열거는 항상 고유성을 보장 할 수 있습니다. 자세한 내용은 블로그를 참조하십시오. http://blog.csdn.net/java2000_net/article/details/3983958 그러나 일반적으로 이것은 상황에서 거의 발생하지 않습니다.

6. 싱글 톤 모드의 인터뷰 질문

 싱글 톤 모드는 프로그래머 기반의 견고 함을 테스트하기 때문에 인터뷰에서 자주 접하게됩니다. 면접관에게 프로젝트를 완료했다고 말하면 면접관이 몇 가지 싱글 톤 디자인을 작성하도록 요청합니다. 모델을 쓸 수 없다면 면접관이 그것을 믿을 것이라고 생각합니까? 면접시 면접 준비를 꼼꼼히해야합니다. 합격하더라도 회사에 불만이있을 가능성이 매우 높습니다. 자, 다시 주제로 돌아 갑시다. 실은 싱글 톤 디자인 패턴의 사람이 거의 면접에서 묻지 않을 것입니다. 중국어 작문 방법은 일반적으로 싱글 톤 디자인 패턴의 게으른 스레드 안전성에 대해 묻기 때문에 모든 사람이 싱글 톤 패턴의 스레드 안전성을 완전히 이해해야합니다. 이러한 패턴에 대해 시간을 갖고 철저하게 학습하고 인터뷰에서 만나십시오. 싱글 톤 모드에 대한 질문을 두려워하지 않을 것입니다.

如果发现博客中有任何问题或者您还有什么疑问欢迎留言,您的支持是我前进的动力
이 블로그가 도움이된다면 좋아요를 누르거나 댓글을 남겨주세요.

재 인쇄 소스를 지정하십시오 : http://blog.csdn.net/dmk877/article/details/50311791

참조 블로그 :
https://segmentfault.com/q/1010000003732558

http://tianweili.github.io/blog/2015/03/02/singleton-pattern/

추천

출처blog.csdn.net/GTC_GZ/article/details/108742184