2017-12-13 9 views
-2

私はクラス2の複数のインスタンスの中で、両方の状態の変化につながる操作を受けます。これはマルチスレッドのアプリケーションであるため、前述の2つのインスタンスのいずれかにアクセスしようとしている他のスレッドはいずれも待ち状態にはなりません。 同期またはロックを使用すると、1つのインスタンスでロックを取得し、2つのオブジェクトで同期ブロックを入れ子にすることはできません。Javaで複数のオブジェクトをロックする

synchronized(obj1){ 
synchronized(obj2){ 
} 
} 

別の潜在的な問題は、外側のオブジェクトはスレッドが待ち続けるロックされているので、内側のオブジェクトOBJ2は、無料であっても例があり得るということです。 この問題に対する最良の解決方法は何でしょうか。

+2

"同期されたブロックを2つのオブジェクトにネストすることはどちらも良い考えではありません。"何故なの?どのようなコードパスがありますか?結局のところ、デッドロックを避けたいので、 'obj2'が空いていても、' obj1'がそうでなければ問題ではありません。 – Kayaman

+0

'sync(obj2){sync(obj1){...}} 'のような別のコードがあると問題になります –

+1

なぜこれを行う必要がありますか?彼らも独立してロックされていますか?私は 'Lock'を使うことを提案し、オブジェクトにアクセスする前に常にそれをロックします。また、 'Lock'を使用すると' tryLock'することができますので、デッドロックを防ぐことができます。 –

答えて

1

ネストされたロックを持つと、2つの異なるスレッドが異なる順序でロックするときに、デッドロックというリスクが発生します。

このようなデッドロックを排除するための普遍的なアプローチはありません。可能な解決策は、:

  1. がロックオブジェクトの全順序を維持し、オブジェクトのみの昇順に(または唯一の降順に)ロックを取得します。

    これは、オブジェクトのいずれかをロックすることなく両方のオブジェクトがわかっている場合に適しています。

  2. tryLock内部ロックのメカニズムを使用します。

    tryLockは、オブジェクトがすでに他のスレッドによってロックされている場合は、即時にfalseを返します。だからプログラムは何とか​​この事件を処理する必要があります。

関連する問題