1. 디자인 패턴이란 무엇입니까?
소프트웨어 엔지니어링에서 설계 패턴은 소프트웨어 설계에서 다양한 일반적인 (반복) 문제에 대한 솔루션입니다. 이 용어는 1990 년대 Erich Gamma와 다른 사람들에 의해 건축 설계 분야에서 컴퓨터 과학에 소개되었습니다.
유명한 4 인 갱 : Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (GOF)
디자인 패턴 : 재사용 가능한 객체 지향 소프트웨어의 기본
2. 싱글 톤 모드
싱글 톤 객체의 클래스는 하나의 인스턴스 만 존재하도록 보장해야합니다. 전체 시스템은 여러 번에만 하나의 전역 객체 만 있으면 시스템의 전반적인 동작을 조정하는 데 도움이됩니다.
예 : 글로벌 정보 구성
싱글 톤 모드의 가장 간단한 구현 :
Public Class Singleton {private singleton () {System.out.println ( "Singleton은 생성"); } private static singleton instance = new Singleton (); 공개 정적 싱글 톤 GetInstance () {return instance; }} 고유성은 개인 생성자와 정적에 의해 결정됩니다.
단점 : 인스턴스가 생성되면 제어하기가 어렵습니다.
클래스 싱글 톤이 처음로드되면 인스턴스가 생성된다는 것을 알고 있습니다.
그러나이 수업에 다른 속성이 있다면
공개 클래스 싱글 톤 {public static int status = 1; private singleton () {system.out.println ( "싱글 톤은 생성"); } private static singleton instance = new Singleton (); 공개 정적 싱글 톤 GetInstance () {return instance; }} 사용시
System.out.println (Singleton.status);
이 예제는 생성됩니다. 아마도이 인스턴스가 생성되기를 원하지 않을 수도 있습니다.
시스템 이이 문제에 특별한주의를 기울이면이 싱글 톤의 구현 방법은 그리 좋지 않습니다.
두 번째 싱글 톤 모드에 대한 솔루션 :
Public Class Singleton {private singleton () {System.out.println ( "Singleton은 생성"); } private static singleton instance = null; public static synchronized singleton getinstance () {if (instance == null) instance = new Singleton (); 반환 인스턴스; }} getInstance () 메소드가 호출되고 스레드 안전이 동기화 된 경우에만 인스턴스를 생성하자.
인스턴스가 생성 될 때 제어합니다.
이 접근법은 게으른 하중의 전형적인 것입니다.
그러나 한 가지 문제는 성능이 높은 동시성 시나리오에 영향을 미친다는 것입니다. 단 하나의 판단만으로 반환되지만 동시성이 높은 경우에는 영향을 미칩니다. 동기화 잠금을 가져와야하기 때문에 다소 영향을 미칩니다.
효율적이 되려면 세 번째 방법이 있습니다.
Public Class StaticSingleton {private staticsingleton () {System.out.println ( "STANTICSINGLETON IS CREATE"); } 개인 정적 클래스 싱글 톤 홀더 {private static stanticsingleton instance = new StaticSingleton (); } public static stanticsingleton getInstance () {return singletonholder.instance; }} 클래스가로드되기 때문에 내부 클래스가로드되지 않습니다. 이를 통해 인스턴스가 getInstance () 호출 될 때만 인스턴스가 생성되고 인스턴스를 생성하는 시간이 제어되고 지연된 하중이 달성됩니다.
성능을 향상시키기 위해 동기화 된 것이 제거되며 정적은 고유성을 보장하는 데 사용됩니다.
3. 불변 모드
클래스의 내부 상태가 만들어지면 전체 수명 동안 변경되지 않습니다.
교체 모드는 동기화가 필요하지 않습니다
변경되지 않은 클래스 만들기 :
공개 최종 클래스 제품 {// 서브 클래스 개인 최종 문자열이 없는지 확인하십시오. // 개인 속성은 다른 객체에서 얻지 못합니다. 개인 최종 문자열 이름; // 최종적으로 속성에 두 번 개인 이중 가격이 할당되지 않음을 보장합니다. 공개 제품 (문자열 번호, 문자열 이름, 이중 가격) {// 객체를 만들 때 데이터는 super ()를 지정해야합니다. // 생성 후에는 이것을 수정할 수 없기 때문에. this.name = 이름; this.price = 가격; } public String getNo () {return no; } public String getName () {return name; } public double getPrice () {반환 가격; }} Java의 변하지 않는 패턴의 경우는 다음과 같습니다.
java.lang.string
java.lang.boolean
java.lang.byte
java.lang.character
java.lang.double
java.lang.float
java.lang.integer
java.lang.long
java.lang.short
4. 미래 모드
핵심 아이디어는 비동기 호출입니다
비 동시성 :
비동기 :
작업이 아직 완료되지 않았으므로 첫 번째 Call_return이 반환됩니다.
그러나이 수익은 쇼핑 주문과 유사하며 향후이 주문에 따라 결과를 얻을 수 있습니다.
따라서이 미래 모델은 "미래"를 얻을 수 있음을 의미합니다. 즉, 주문 또는 계약이 "약속"이며 향후 결과를 제공 할 것입니다.
미래 모드의 간단한 구현 :
발신자가 얻는 것은 RealData가 구축 속도가 느리기 때문에 처음에 미래화 될 수있는 데이터입니다. 미래에 언젠가 RealData는 Futuredata를 통해 얻을 수 있습니다.
코드 구현 :
공개 인터페이스 데이터 {public String getResult (); } public class futuredata는 데이터를 구현합니다. {Protected RealData realData = null; // futuredata는 RealData 포장지 보호 된 부울 isready = false입니다. public synchronized void setRealData (RealData RealData) {if (isready) {return; } this.RealData = RealData; isready = true; notifyall (); // realData가 주입되었습니다. // realData가 주입되었다는 것을 알기 위해 항상 기다립니다} catch (InterpruptedException e) {}} retud realdata.result; // realData에 의해 구현}} public class realData는 데이터 {보호 된 최종 문자열 결과; Public RealData (String para) {// RealData의 구성은 매우 느리기 때문에 사용자가 오랫동안 기다려야합니다. 여기서 우리는 stringbuffer sb = new StringBuffer ()를 시뮬레이션하기 위해 수면을 사용합니다. for (int i = 0; i <10; i ++) {sb.append (para); {// 매우 느린 작동 스레드 대신 여기에서 sleep를 사용하십시오. Sleep (100); } catch (InterruptedException e) {}} result = sb.toString (); } public String getResult () {return result; }} public class client {public data request (final string querystr) {Final Futuredata Future = new futuredata (); new Thread () {public void run () {// realData는 빌드가 매우 느립니다. Future.setRealData (RealData); } } }.시작(); 미래를 반환; // futuredata가 즉시 반환됩니다}} public static void main (String [] args) {client client = new Client (); // realData data data = client.request ( "name") 대신 Futuredata이므로 즉시 반환됩니다. System.out.println ( "요청 완료"); {// 여기에서 다른 비즈니스 로직을 처리하는 대신 수면을 사용할 수 있습니다. // 이러한 비즈니스 로직을 처리하는 과정에서 RealData는 대기 시간 스레드를 최대한 활용하여 수면 (2000)을 최대한 활용합니다. } catch (InterruptedException e) {} // 실제 데이터 시스템을 사용합니다. }JDK에는 많은 미래 모드 지원이 있습니다.
다음으로 JDK가 제공 한 클래스와 메소드를 사용하여 지금 코드를 구현하십시오.
import java.util.concurrent.callable; public class realdata 구현 호출 가능 <string> {private String para; public realdata (String para) {this.para = para; } @override public String Call ()은 예외를 던지려고 {StringBuffer sb = new StringBuffer (); for (int i = 0; i <10; i ++) {sb.append (para); try {thread.sleep (100); } catch (InterruptedException e) {}} return sb.toString (); }} import java.util.concurrent.executionException; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.futuretask; public static void main (string [] args). FutureTask FutureTask <string> Future = New FutureTask <string> (New RealData ( "A")); ExecutorService Executor = Executor.NewFixedThreadPool (1); // 위의 예에서 Client.Request ( "A")와 동등한 FutureTask를 실행합니다. System.out.println ( "요청 완료"); 시도 {// 추가 데이터 작업은 여전히 여기에서 수행 할 수 있으며 다른 비즈니스 로직 스레드를 처리하는 대신 수면을 사용할 수 있습니다. Sleep (2000); } catch (InterpruptedException e) {} // data.getResult ()와 동등한 경우 call () 메소드의 리턴 값을 가져옵니다. }} 여기서 주목해야 할 것은 FutureTask는 미래의 기능과 실행 가능한 기능을 가진 클래스라는 것입니다. 그래서 다시 실행되고 마침내 얻을 수 있습니다.
물론 미래를 호출 할 때 실제 데이터가 준비되지 않은 경우 데이터가 준비 될 때까지 여전히 차단 상황이 발생합니다.
물론 더 쉬운 방법이 있습니다.
import java.util.concurrent.executionException; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.future; public static void main (strings) {executecution {huplestement retinceter retomection {huplatedexemention {huplictedecution retince retence executors.newfixedthreadpool (1); // 위의 예에서 Client.Request ( "A")와 동등한 FutureTask를 실행하십시오. System.out.println ( "요청 완료"); 시도 {// 추가 데이터 작업은 여전히 여기에서 수행 할 수 있으며 다른 비즈니스 로직 처리 스레드 대신 수면을 사용하십시오. } catch (InterpruptedException e) {} // data.getResult ()에 해당하는 경우 Call () 메소드의 리턴 값을 가져옵니다. }} Callable에는 리턴 값이 있으므로 향후 객체를 직접 반환 할 수 있습니다.
5. 생산자와 소비자
프로듀서 소비자 모델은 클래식 한 멀티 스레드 디자인 모델입니다. 여러 스레드 간의 협업을위한 좋은 솔루션을 제공합니다. 생산자 소비자 모델에는 일반적으로 두 가지 유형의 스레드, 즉 여러 생산자 스레드와 여러 소비자 스레드가 있습니다. 생산자 스레드는 사용자 요청을 제출하는 책임이 있으며 소비자 스레드는 생산자가 제출 한 작업을 구체적으로 처리 할 책임이 있습니다. 생산자와 소비자는 공유 메모리 버퍼를 통해 통신합니다.
과거에 Java를 사용하여 생산자와 소비자를 구현하는 다양한 방법을 구현하기 위해 기사를 작성 했으므로 여기서 설명하지 않습니다.