8

はこのanswerを参照してください。それは言う:可変オブジェクトのロック - なぜそれは悪い習慣とみなされますか?

六本当に悪い例。

...

可変フィールドのロック。例えば同期(オブジェクト){オブジェクト= ...;変更可能なフィールドにロックすると間違って何}

object場合finalとして宣言されていますが、不変なクラスはありませんでしたか?

+1

私はあなたが不変クラス(のみ不変フィールドを含むクラス)に変更可能なフィールドを混乱だと思います。 –

答えて

14

他のスレッドがクリティカルセクション内の参照を変更した場合、スレッドは同じ参照を認識しなくなり、同じオブジェクト上で同期しないため制御されない状態になるため、悪い考えです。例:

synchronized(lock1) { 
    lock1 = new Object(); 
    sharedVariable++; 
} 

2つのスレッドがこのクリティカルセクションに入力しようとしていると仮定します。スレッド1が入り、スレッド2が待機します。スレッド1が入り、lock1を再割り当てして処理を進めます。スレッド2は、スレッド1が獲得したものとは異なるロックを見ることができます。これはフリーでもあり、クリティカルセクションにも入ることができます。楽しみが続く!

オブジェクトがfinalの場合は、別のオブジェクトに参照を再割り当てできないため、上記の問題はもう適用されません。

5

は「変更可能な」ここに右の言葉ではありません。可変オブジェクト、つまり状態のオブジェクトをロックすることは大丈夫です。何が問題なのは、フィールドをロックして変更し、別のスレッドが同じオブジェクトをロックすることを期待することです。

1

私は可変オブジェクトをロックすること自体が悪いとは思わない。それを正しくするのは非常に難しいです。アクターのような同時処理のための他のモデルもあります。私は、JavaとScalaの両方から使用できるAkkaを調べることをお勧めします。これは非常に堅実な実装です。

関連する問題