2017-01-20 7 views
0

は、我々はこのようのsyncronizationを使用します。いつかのsyncronizationいつものように

Class A{ 
    public void method1{ 
     syncronized(this){ 
     } 
    } 
    public void method2{ 
     syncronized(this){ 
     } 
    } 
} 

、私はこのようなコードを見つけました:クラスCの場合と同様に

Class B{ 
     public void method3{ 
      syncronized(B.class){ //class level lock but lock itself 
      } 
     } 
    } 
Class C{ 
     public void method4{ 
      syncronized(B.class){/class level lock but lock other class 
      } 
     } 
    } 

を示し、それがBを使用しますクラスをモニタとして使用できます。クラスCインスタンスC1とスレッドt3アクセスクラスBインスタンスB1の2つのスレッドt1とt2がアクセスしていると仮定すると、t1がC1にアクセスするときにインスタンスB1またはクラスBに影響はありますか? はBクラスの "this"のようなB.classの役割ですか?

+0

私はそれがコピー/ペーストプログラミングのアーティファクトだと思います。クラスCはおそらくクラスBをコピーし、名前を変更し、B固有のものを削除することによって作成されました。 – sisyphus

+0

@sisyphusいいえ、それは正しいコードです。問題を議論する例として。 – lawrence

+0

最初のコードに示すように、通常は同期を使用しません。メソッドを 'synchronized'にするのではなく、' this'を手動で同期させるのは間違いです。一方、第2の例は悪く、エラーを起こしやすいプログラミングである。 – Kayaman

答えて

0

プロダクションコードでこのようなことが確認されたら、問題が発生している可能性があります。しかし、理解するのは比較的簡単です。

B.method3()C.method4()の両方の同期にBのクラスインスタンスが使用されています。したがって、呼び出されているインスタンスに関係なく、一度に1つのスレッドのみがこれらのメソッドのいずれかに入ることができます。あなたがBのクラスインスタンス上で同期するものが増えない限り、他には何の効果もありません。その理由で使用するのはかなり鈍い武器です。取得しているシリアライゼーションのレベルは明確に定義されていません。

しかし、これは適切なグローバルなJVMレベルの同期ではありません.Bclassの異なるインスタンスが異なるクラスローダーに存在する可能性があるため、このような狂気を起こした場合に起こることに非常に注意する必要があります。一度に1つだけアクセスすべきグローバルリソースを保護しようとしている場合は、代替アプローチを検討することをお勧めします。

より一般的な観点から、それは CメソッドがB.class上で同期ので、時間をかけて、ことをしている必要があり、なぜそれがすべてで明確ではありませんBとCの間の依存関係のこの種を作成するには悪い考えです理由が失われる可能性があります。 Bの変更は、がこのようにしてBで同期する必要がなくなった(または適切である)ことを意味しますが、あなたは知ることができません。

+0

ありがとう!私はあなたが言ったことを理解しようとする – lawrence

関連する問題