Javaのsynchronizedキーワード並行プログラミングは最も一般的に使用されるツールは、最も重要なツールの一つです。今日の下にその意味を探求します
テストするために、2つのクラス、コードの二つの異なるクリティカルセクションを書きます。
次の4つの試験溶液、ロックの4種類に対応する各プログラム:ロックオブジェクト:同期(本)、このクラスのロック:親クラス・ロックは、(Me.class)同期:同期(Parent.class)、カスタムロックオブジェクト
1.異なるスレッドで同じオブジェクトを実行します
異なるスレッドでクラスの異なるオブジェクトと2.を実行します
3.異なるクラスは異なるスレッドで実行されている、異なるオブジェクトの(共通の親クラスを持っています)
別のスレッドで実行4.異なるクラスの異なるオブジェクトの(なし共通の親クラス)、
テスト結果:
オブジェクトロックでは、一つだけできクリティカルセクションへの排他的アクセス。
これによりロックは、1及び2は、クリティカル領域に相互に排他的なアクセスであってもよいです。
共通の親クラスをロックし、すべての重要な領域への排他的アクセスです。(注第四テストプログラムを使用している場合、2つのオブジェクトが共通の親クラスを持っていないので、このいわゆる共通の親クラスロックすることを、実際に自分に似直接この2つのクラスに関係のない第三者であり、ロックオブジェクトの定義が、このカスタムロックオブジェクトは、通常のオブジェクトではなく、クラスオブジェクト)
重要な領域へのすべての缶の排他的アクセスカスタムロックオブジェクト、と。
/ ** * synchronizedキーワードテスト * * @author zhangxz * @date 2019年11月18日午前11時07分 * / パブリック クラスSynchronizedTest { プライベート 静的 最終同期同期= 新しい同期(); パブリック 静的 ボイドメイン(文字列[]引数)がスローInterruptedExceptionあるが{ スレッドA threadA1 = 新しいスレッドA(); スレッドA threadA2 = 新しいスレッドA(); ThreadB threadB = 新しいThreadB(); // testOneRunnable(threadA1)。 // testTwoRunnable(threadA1、threadA2)。 testTwoRunnable(threadA1、threadB)。 } 静的 クラス同期{} // 2つの異なるスレッドで、コールを実行可能なオブジェクトを使用する 静的 ボイドtestOneRunnable(Runnableを実行可能){ スレッド1スレッド = 新しいスレッドを(実行可能)。 スレッド2スレッド = 新しいスレッドを(実行可能)。 thread1.start(); thread2.start(); } // 2つの異なるスレッドで呼び出さを使用して、2つの実行可能なオブジェクト、 静的 ボイドtestTwoRunnable(Runnableをrunnable1、Runnableをrunnable2){ スレッド1スレッド = 新しいスレッド(runnable1を)。 スレッド2スレッド = 新しいスレッド(runnable2を)。 thread1.start(); thread2.start(); } 静的 クラスABParent { } 静的 クラスは、スレッドA / * 延びABParent * / 実装のRunnable { @オーバーライド 公共 のボイドの実行(){ // 同期(本){ // 同期(ThreadA.class){ // 同期(ABParent.class){ 同期(シンク){ しようと{ Thread.sleep( 10 )。 System.out.println( "スレッドの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "スレッドの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "スレッドの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 } キャッチ(InterruptedExceptionあるE1){ e1.printStackTrace(); } } } } 静的 クラスは ThreadB / * 延びABParent * / 実装のRunnable { @オーバーライド 公共 のボイドの実行(){ // 同期(本){ // 同期(ThreadB.class){ // 同期(ABParent.class){ 同期(シンク){ しようと{ Thread.sleep( 10 )。 System.out.println( "スレッドBの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "スレッドBの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "スレッドBの処理" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 } キャッチ(InterruptedExceptionあるE1){ e1.printStackTrace(); } } } } }
追加試験
除去同期1つのクラス、すなわち、他のではない重要な領域です。そして、それをテストし、私は関係なく、ロックとクリティカルゾーンで、両方の排他的アクセスを実現することができないことがわかりました。
2つの異なるロックにオブジェクト・クラスのロックを二同期コードブロックが異なるロックを保持しているため、重要な領域を構成することができないので、排他的アクセスを達成することができません。
異なるオブジェクト同期方法であって、次のコードで3試験。試験結果:同一のオブジェクトと同期化方法は、クリティカルエリアを構成するには、相互に排他的にアクセスすることができます。
静的 ボイドtestDifferentMethodsInOneObject(種皮種皮){ 実行可能runnable1 =() - > { 試み{ testA.MethodA(); testA.MethodB(); } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } }。 実行可能runnable2 =() - > { 試み{ testA.MethodB(); testA.MethodA(); } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } }。 スレッド1スレッド = 新しいスレッド(runnable1を)。 スレッド2スレッド = 新しいスレッド(runnable2を)。 thread1.start(); thread2.start(); } 静的 クラス種皮{ 公共 同期 無効 MethodAは()スロー例外:InterruptedExceptionを{ Thread.sleep( 10 )。 System.out.println( "方法における工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "方法における工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "方法における工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 } 公共 同期 のボイド MethodBは()スロー例外:InterruptedExceptionを{ Thread.sleep( 10 )。 System.out.println( "方法Bにおける工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "方法Bにおける工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 System.out.println( "方法Bにおける工程" + にThread.currentThread()のgetName()。)。 Thread.sleep( 10 )。 } }
同期最終的な結論の使用:
1.クリティカルと非クリティカル領域は、排他的アクセスを実現することができません。
最小サイズは、ロックオブジェクトのロックを同期されるので、2と同じオブジェクト(たとえ異なる同期コードブロックの重要な領域は、単一のクリティカル領域を構成する。ここで疑い、メンバ変数も、これを修正することができるように同期可能にする方法の詳細。)、限り、あなたは排他的アクセスをロックすることができますよう。
同じクラスの3異なるオブジェクト/異なるクラスの異なるオブジェクトは、両方の同期コード・ブロックは、同じ場所にいませんが、長いロックの粒度などとして、2つのコード・ブロックをカバーするために十分な大きさで、2つのコードブロッククリティカルエリアを構成している、あなたは相互に排他的なアクセスを実現することができます。
前記共通の変数がロックオブジェクトとして定義されているので、限り、所定のコードブロックはロックに同じでなければならないように、クリティカルセクションの任意の場所への排他的アクセスを達成することができます。