1コース説明します
1.1は、なぜあなたは、ダブルチェックを使用したくありません
1.2欠点ダブルチェック
1.3命令の並べ替えを説明
1.4命令並べ替えメタファー(理解)
命令の並べ替えの問題を解決する方法1.5
2コードのチュートリアル
2.1コードチュートリアル(ダブルチェック問題解決クラスオブジェクトのロックとロック)1
2.2コードチュートリアル2(揮発性アプリケーション:問題を解決するための並べ替え)
1コース説明します
1.1は、なぜあなたは、ダブルチェックを使用したくありません
ブロックされたときに、マルチスレッド、なぜならスレッドの最後のレッスンでは、他のスレッドがクラスにアクセスすることができない、ブロックされています。これは、主にこのような問題を解決するために使用はるかに低いとのダブルチェックです。
ダブルチェックは、ロックが解除されたときに、この場合には、むしろクラスの外側よりも、プロセスに複数のスレッドの閉塞を作ることができ、実行速度が速く、効率を大幅に向上させることができます。
1.2欠点ダブルチェック
実行中のJavaは、発生する可能性がリオーダリング命令を割り当てられている(第一の)スレッドのオブジェクトを引き起こす(2ドリル参照このセクションのコードステートメントの後ろ2.1)問題が、しかし後(後スレッドBが初期化されていません今オブジェクトが空でないため)の判断を渡すために、訪問はまだオブジェクトを完全に初期化されていないスレッドBのスレッドで、その結果、()のオブジェクトへのアクセスに始めています。完全な初期化の対象とわけではないので、システムは例外を報告します。
1.3命令の並べ替えを説明
初期化時間は、実際には3つの段階で行わ:
オブジェクトに割り当てられたメモリ
Bオブジェクトを初期化します
オブジェクトに割り当てられたメモリへのCに配置されたオブジェクト点を
通常の状況下では、ABCのに従い、実行順序は、だけでなく、逆に、BCへのチャンスがあります。
単一の実行スレッドのこの時間は、そこに問題ありませんが、また、作業の効率を向上させることができます。
1.4 命令並べ替え列のアナロジー(理解)
これは次のように比較することができます。
人々は、食べに来ます
まず、食堂の食事を思い付きます
Bこの人が誰であるかを決定し、
C男は、この食事を取りました
解決方法1.5 命令並び替え順序の問題を
二つの方法:
並べ替えが発生しないように、プロセスは、各によって実行される通常の初期化ステップ2.2に従ってコードのセクションを参照
Bスレッドは、後でスレッド問題の最初の並べ替えを見ることが許されていません
2コードのチュートリアル
2.1コードチュートリアル1(ロックとロックの問題のような解像度のオブジェクト)
テストカテゴリ:
パッケージcom.geely.design.pattern.creational.singleton。 パブリック クラスのテスト{ / * パブリック静的無効メイン(文字列[] args){ //这样写异常、因为构造方法私有 // LazySingleton lazySingleton =新しいLazySingleton()。 LazySingleton lazySingleton = LazySingleton.getInstance()。 System.out.println(lazySingleton)。 } * / パブリック 静的 ボイドメイン(文字列[]引数){ スレッドスレッド1 = 新しいスレッド(新しいT())。 スレッド2スレッド = 新しいスレッド(新しい T()); thread1.start(); thread2.start(); System.out.printlnは( "エンディング!!!" ); } }
Threadクラス:
パッケージcom.geely.design.pattern.creational.singleton。 / ** *注:该类为线程类、调用LazySingleton * / パブリック クラス Tは、実装のRunnable { / * @Override 公共ボイドラン(){ LazySingleton lazySingleton = LazySingleton.getInstance()。 System.out.println(にThread.currentThread()のgetName()+ "===" + lazySingleton。)。 } * / @Override 公共 ボイドラン(){ LazyDoubleCheckSingleton lazyDoubleCheckSingleton = LazyDoubleCheckSingleton.getInstance()。 System.out.println(にThread.currentThread()。のgetName() + "===" +lazyDoubleCheckSingleton); } }
エンティティクラス:
パッケージcom.geely.design.pattern.creational.singleton; パブリック クラスLazyDoubleCheckSingleton { / * プライベート、他の外部クラスの属性、プロパティを呼び出すことはできません、セキュリティ * / プライベート 静的 LazyDoubleCheckSingleton lazyDoubleCheckSingleton = ヌル; / ** その他*コンストラクタのプライベート、クラスをインスタンス化することができないクラス * / プライベートlazyDoubleCheckSingleton(){ } / ** *異なる表現で、 * * @return * / パブリック 静的lazyDoubleCheckSingletonのgetInstance(){ IF(lazyDoubleCheckSingleton == NULL){ 同期(LazyDoubleCheckSingleton.class){ IF(lazyDoubleCheckSingleton == NULL){ lazyDoubleCheckSingleton =新しいLazyDoubleCheckSingleton()。 } } } 戻りlazyDoubleCheckSingletonと、 } }
印刷結果:
"C:\プログラムファイル\のJava \ jdk1.7.0_79 \ binに\ののjava.exe" -agentlib:JDWP =交通= dt_socketという、= 127.0.0.1アドレス:C:9096は、= Y、サーバー= N -javaagentを中断\ Users \ユーザーweijingli \ .IdeaIC2018.1 \ SYSTEM \ captureAgent \デバッガ-agent.jar =ファイル:/ C:/Users/weijingli/AppData/Local/Temp/capture.propsの-Dfile.encoding = UTF-8 -classpath「C :\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ charsets.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ deploy.jar; C:\プログラムファイル\のJava \ jdk1 .7.0_79 \ JRE \ libに\ extに\アクセス・ブリッジ64.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ extに\ dnsns.jar; C:\プログラムファイル\のJava \ jdk1 .7.0_79 \ JRE \ libに\ extに\ jaccess.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ extに\ localedata.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ extに\ sunec.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ extに\ sunjce_provider.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ ext \のsunmscapi.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ extに\ zipfs.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ javaws.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ jce.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ jfr.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ jfxrt.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\のjsse.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\管理-agent.jar; C :\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ plugin.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ resources.jar; C:\プログラムファイル\のJava \ jdk1 .7.0_79 \ JRE \ libに\ rt.jarの; F:\ xiangmu3 \新\アイデア\ design_pattern \ターゲット\クラス; D:\ javaの\のdevolopKitの\アイデア\ anZhのIntelliJ IDEA Community Editionを2018年1月4日\ \ libに\ idea_rt。瓶」0_79 \ JRE \ libに\ jfr.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ jfxrt.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ JSSE。瓶; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\管理-agent.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ plugin.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ resources.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ rt.jarの; F:\ xiangmu3 \新\アイデア\ design_pattern \ターゲット\クラス; D:\のJava \ devolopKitの\アイデア\ anZh \のIntelliJ IDEA Community Editionを2018年1月4日\ libに\ idea_rt.jar」0_79 \ JRE \ libに\ jfr.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ jfxrt.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ JSSE。瓶; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\管理-agent.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ plugin.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ resources.jar; C:\プログラムファイル\のJava \ jdk1.7.0_79 \ JRE \ libに\ rt.jarの; F:\ xiangmu3 \新\アイデア\ design_pattern \ターゲット\クラス; D:\のJava \ devolopKitの\アイデア\ anZh \のIntelliJ IDEA Community Editionを2018年1月4日\ libに\ idea_rt.jar」\ xiangmu3 \新\アイデア\ design_pattern \ターゲット\クラス; D:\ Javaの\のdevolopKitの\アイデア\ anZhのIntelliJ IDEA Community Editionの\ 2018年1月4日\ libに\ idea_rt.jar」\ xiangmu3 \新\アイデア\ design_pattern \ターゲット\クラス; D:\ Javaの\のdevolopKitの\アイデア\ anZhのIntelliJ IDEA Community Editionの\ 2018年1月4日\ libに\ idea_rt.jar」com.geely.design.pattern.creational.singleton.Test :ターゲットVM、アドレスに接続 '127.0.0.1:9096'、輸送: 'ソケット'を 结束了!!! スレッド -0 === com.geely.design .pattern.creational.singleton.LazyDoubleCheckSingleton @ 8fea539 :ターゲットVM、アドレスから切断 '127.0.0.1:9096'、輸送: 'ソケット' スレッド -1 === com.geely.design.pattern.creational.singleton.LazyDoubleCheckSingleton @ 8fea539 プロセス終了コードで終了 0
2.2 コードチュートリアル2(揮発性アプリケーション:問題を解決するための並べ替え)
Java言語仕様の状態:すべてのスレッドは、Javaプログラムが順守しなければならない実行スレッド内セマンティクス、
スレッド内のセマンティクスは、並べ替えがシングルスレッドプログラムの実行結果の中に変化しないことを保証します。
言い換えれば、スレッド内のセマンティクスは、結果を変更しないものをシングルスレッド、シングルスレッドのプログラム実行の並べ替えが可能になります。
用パッケージ変更com.geely.design.pattern.creational.singleton、 パブリック クラスLazyDoubleCheckSingleton { / * 1つの、揮発性のキーワードの役割 データは、現在のプロセッサのキャッシュラインをメモリに書き戻される、キャッシュは、他のCPUメモリを動作しますデータ・メモリ・アドレスが有効ではありません。彼らは、メモリを共有し、同期データから。だから、オペレーティング・メモリの可視性を保存します。J 2 * / プライベート 揮発性 スタティック LazyDoubleCheckSingleton lazyDoubleCheckSingleton = NULL ; / ** *プライベートコンストラクタ、他のないクラスがインスタンス化クラス * / プライベートLazyDoubleCheckSingleton(){ } / ** *異なる表現で、 * * @returnの * / 公共 静的LazyDoubleCheckSingletonのgetInstance(){ 場合(lazyDoubleCheckSingleton == NULL ){ 同期(LazyDoubleCheckSingleton。クラス){ 場合(lazyDoubleCheckSingleton == NULL ){ lazyDoubleCheckSingleton = 新しいLazyDoubleCheckSingleton()。 } } } 戻りlazyDoubleCheckSingletonと、 } }
スレッド内のセマンティクスは、並べ替えがシングルスレッドプログラムの実行結果の中に変化しないことを保証します。
言い換えれば、スレッド内のセマンティクスは、結果を変更しないものをシングルスレッド、シングルスレッドのプログラム実行の並べ替えが可能になります。