1。デザインパターンとは何ですか
ソフトウェアエンジニアリングでは、設計パターンは、ソフトウェア設計におけるさまざまな一般的な(繰り返し)問題に提案されたソリューションです。この用語は、1990年代にエリッヒガンマなどによって建築設計の分野からコンピューターサイエンスに導入されました。
有名な4人のギャング:エーリッヒ・ガンマ、リチャード・ヘルム、ラルフ・ジョンソン、ジョン・ウリシド(GOF)
設計パターン:再利用可能なオブジェクト指向ソフトウェアの基本
2。シングルトンモード
Singletonオブジェクトのクラスは、1つのインスタンスのみが存在することを保証する必要があります。多くの場合、システム全体には1つのグローバルオブジェクトのみが必要です。これは、システムの全体的な動作を調整するのに役立ちます。
例:グローバル情報構成
シングルトンモードの最も単純な実装:
パブリッククラスのsingleton {private singleton(){system.out.println( "singleton is create"); } private static singleton instance = new Singleton(); public static singleton getInstance(){return instance; }}一意性は、プライベートコンストラクターと静的によって決定されます。
短所:インスタンスを生成する場合、制御が困難です
クラスのシングルトンが最初にロードされると、インスタンスが生成されることはわかっています。
しかし、このクラスに他のプロパティがある場合
パブリッククラスSingleton {public static int status = 1; private singleton(){system.out.println( "Singleton is Create"); } private static singleton instance = new Singleton(); public static singleton getInstance(){return instance; }}使用するとき
System.out.println(singleton.status);
この例が作成されます。このインスタンスが現時点で生成されたくないのかもしれません。
システムがこの問題に特別な注意を払っている場合、このシングルトンの実装方法はあまり良くありません。
2番目のシングルトンモードの解決策:
パブリッククラスのsingleton {private singleton(){system.out.println( "singleton is create"); } private static singleton instance = null; public static同期Singleton getInstance(){if(instance == null)instance = new Singleton();インスタンスを返す; }} Instanceを作成して、GetInstance()メソッドが呼び出され、スレッドの安全性が同期して確実に保証されます。
これにより、インスタンスが作成される時期が制御されます。
このアプローチは、怠zyなロードの典型です。
しかし、1つの問題は、パフォーマンスが高い並行性シナリオに影響を与えることです。 1つの判断のみで返されますが、同時性が高い場合に影響がありますが、同期ロックを取得する必要があるため、多かれ少なかれ影響があります。
効率的になるためには、3番目の方法があります。
Public Class StaticSingLeton {private staticsingleton(){system.out.println( "staticsingleton is create"); } private static class singletonholder {private static staticsingleton instance = new StaticSingLeton(); } public static staticSingleton getInstance(){return singletonholder.instance; }}クラスがロードされると、その内側のクラスはロードされません。これにより、getInstance()が呼び出された場合にのみインスタンスが生成され、インスタンスの生成時間が制御され、遅延荷重が達成されます。
また、同期されたパフォーマンスを向上させるために削除され、一意性を確保するために静的が使用されます。
3。不変モード
クラスの内部状態が作成された後、それは人生全体で変化しません。
変更モードでは、同期する必要はありません
変更されていないクラスを作成します:
パブリックファイナルクラスの製品{//サブクラスのプライベートファイナルストリング番号がないことを確認してください。 //プライベート属性は、他のオブジェクトによって取得されませんプライベート最終文字列名。 //最終的な保証属性が2倍のプライベート2倍の価格を割り当てられないことを保証します。パブリック製品(文字列番号、文字列名、二重価格){//オブジェクトを作成する場合、データはsuper()を指定する必要があります。 //作成後、これを変更できないため、no = no; this.name = name; this.price = price; } public string getno(){return no; } public string getname(){return name; } public double getPrice(){return price; }} 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は返されます。
しかし、このリターンはショッピングの注文に似ており、将来のこの注文に基づいて結果を得ることができます。
したがって、この将来のモデルは、「将来」を取得できることを意味します。つまり、順序または契約は「約束」であり、将来の結果が得られます。
将来のモードの簡単な実装:
発信者が取得するのはデータです。これは、realldataが構築が遅いため、最初は未来のものかもしれません。将来のある時点で、redataはfuturedataを通じて取得できます。
コード実装:
パブリックインターフェイスデータ{public string getResult(); } public class futuredataはデータを実装します{protected realdata realdata = null; // futuredataはreldataラッパーで保護されているブール症= false; public同期void setrealdata(realdata realdata){if(isready){return; } this.realdata = realldata; isready = true; notifyall(); // Realdataが注入されました、Notify getResult()} public synchronized string getResult()// realdata構造が{while(!isreading){try {wait(); // realeldataが注入されていることを知るためにいつも待ってください} catch(arternedexception e){}} realeldata.result; // Realdataによって実装された}} public class Realdataはデータを実装します{保護された最終文字列結果。 public Realdata(String para){// realldataの構築は非常に遅く、ユーザーが長い間待つ必要があります。ここでは、Sleepを使用してStringBuffer sb = new StringBuffer()をシミュレートします。 for(int i = 0; i <10; i ++){sb.append(para); {//非常に遅い操作スレッドの代わりにここで睡眠を使用する{//スリープ(100); } catch(arternedexception e){}} result = sb.toString(); } public string getResult(){return result; }} public class client {public data request(final string querystr){final futuredata future = new futuredata(); new shood(){public void run(){// reaLdataはビルドが非常に遅いため、//別のスレッドでrealdata realdata = new realdata(querystr); future.setRealdata(realdata); } } }。始める();未来を返す; // futuredataはすぐに返されます}} public static void main(string [] args){client client = new Client(); //これはすぐに返されます。なぜなら、あなたが得るものはrealdata data data = client.request( "name"); System.out.println( "要求完了"); try {//ここでは、他のビジネスロジックを処理する代わりに睡眠を使用できます//これらのビジネスロジックを処理するプロセスで、realdataが作成され、待機時間スレッドを最大限に活用します。 } catch(arternedexception e){} // real data system.out.println( "data =" + data.getResult());を使用します。 }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()throws Exception {stringbuffer sb = new StringBuffer(); for(int i = 0; i <10; i ++){sb.append(para); {thread.sleep(100); } catch(arternedexception e){}} return sb.toString(); }} java.util.concurrent.executionexception;インポートjava.util.concurrent.executorservice;インポートjava.util.current.executors; import java.util.concurtors; import java.util.concurrent.futuretask; public class futuremain {public static void main(] FutureTask <String> Future = new FutureTask <String>(new realdata( "a")); executorservice executor = executors.newfixedthreadpool(1); //上記の例でclient.request( "a")に相当するfuturetaskを実行します。//ここでスレッドを有効にしてrealdata call()を実行し、executor.submit(future)を実行します。 System.out.println( "要求完了"); {//追加のデータ操作はここでも実行でき、他のビジネスロジックスレッドを処理する代わりに睡眠を使用できます。 } catch(arturtedexception e){} // data.getResult()に相当し、call()methodの返品値を取得します// call()メソッドが現時点で実行されない場合でも、system.out.println( "data =" + future.get())を待ちます。 }}ここで注意する必要があるのは、FutureTaskが将来の機能と実行可能な機能を備えたクラスであるということです。そのため、再び実行し、最終的にそれを取得できます。
もちろん、future.get()を呼び出すときに実際のデータが準備ができていない場合、データが準備されるまでブロッキング状況を引き起こします。
もちろん、より簡単な方法があります:
java.util.concurrent.executionexception;インポートjava.util.concurrent.executorservice; Import java.util.current.executors; Import java.util.concurrent.future; public class futuremain2 {public void main [] execurtedexcections executedexcections executedexecutescection { executors.newfixedthreadpool(1); //上記の例でclient.request( "a")に相当するfuturetaskを実行します。 System.out.println( "要求完了"); {//追加のデータ操作をここで実行できます。他のビジネスロジック処理スレッドの代わりに睡眠を使用することができます。スリープ(2000); } catch(arternedexception e){} // data.getResult()に相当する、call()メソッドの返された値を取得// call()メソッドが現時点で実行されない場合、System.out.printlnはまだsystem.out.println( "data =" + future.get())を待っています。 }} Callableには返品値があるため、将来のオブジェクトを直接返すことができます。
5。プロデューサーと消費者
プロデューサー - 消費者モデルは、古典的なマルチスレッド設計モデルです。複数のスレッド間のコラボレーションに適したソリューションを提供します。プロデューサー - 消費者モデルには、通常、2つのタイプのスレッドがあります。つまり、いくつかのプロデューサースレッドといくつかの消費者スレッドがあります。プロデューサースレッドはユーザーリクエストを送信する責任がありますが、消費者スレッドはプロデューサーが提出したタスクを特に処理する責任があります。プロデューサーと消費者は、共有メモリバッファーを介して通信します。
私は過去に、Javaを使用して生産者と消費者を実装するさまざまな方法を実装するための記事を書いてきたので、ここでは説明しません。