2

次のコードスニペットを検討します。

 Object bar1  = new ... ; 
 Object bar2 = new ... ; 


 Object foo = (either bar1 or bar2) ; 

これで、プログラムのさまざまな時点でfooをbar1またはbar2にすることができます。同期(foo)が対応するbar1またはbar2をロックすることを確認したかっただけです。オブジェクトがJavaでコピーされないことを考えると、これは最も可能性の高いシナリオのようです。これは正しいです?

4

3 に答える 3

6
Object bar1 = new Object();
Object foo = bar1;
synchronized(foo) {
    ...
}

foo==でロックされbar1ます。

ただし、これは奇妙でエラーが発生しやすい構造です。例えば:

  • スレッド1がメソッドに到着し、foo == bar1
  • スレッド1は同期ブロックに到着し、bar1をロックします
  • スレッド2がメソッドに到着し、foo == bar2
  • スレッド2は同期ブロックに到着し、bar2をロックします

これで、同期ブロックを同時に実行している2つのスレッドができました。私はあなたがそれを望む理由を本当に見つけることができません。その場合、ブロックはおそらく同期されるべきではなく、別のロック戦略を使用する必要があります。

この関連記事も参照してください。

于 2012-08-21T10:44:22.863 に答える
2

はい。参照ではなく、基になるオブジェクトで同期しています。

各オブジェクトにはモニターが関連付けられており、を使用するときにロックしているのはこれですsynchronizedここから:

Java仮想マシンでは、すべてのオブジェクトとクラスが論理的にモニターに関連付けられています。オブジェクトの場合、関連するモニターはオブジェクトのインスタンス変数を保護します。クラスの場合、モニターはクラスのクラス変数を保護します

于 2012-08-21T10:45:44.813 に答える
2

はい、それはどのオブジェクトfooが指しているかをロックします。fooただし、次のようなことを避けるために、ファイナルを作成することをお勧めします。

Object foo = bar1;
synchronized(foo) {
   foo = bar2;
}

いくつかのスレッドが異なるロックを見ると大混乱を引き起こすからです。この質問も参照してください:可変オブジェクトのロック-なぜそれが悪い習慣と見なされるのですか?

于 2012-08-21T10:47:05.590 に答える