2012-02-23 22 views
2

私はObjective-Cプロジェクトでいくつか同期しています。コードは次のようになります。@synchronized(self)のデッドロックを回避する方法は?

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 
    //some code 
    @synchronized(self) { //at this line deadlocks 
     //some code 
    } 
    //some code 
} 

と、この行(@synchronized)に、デッドロックが常に発生します。このデリゲートメソッドは非常に頻繁に呼び出されることもわかります。

このようなデッドロックを回避するにはどうすればよいですか?

+0

あなたは '@synchronized(self)'を使っていますか? –

+0

私は共有変数、例えばデフォルト値やデータにアクセスするためにこれを使用しています。 –

答えて

4

他のスレッドからのロックが@synchronized(self)で取得されたロックを解放することはないことを意味します。別のスレッドで起こっている別のスレッドからロックを取得しようとしています。この問題を探してください(一時停止すると、別のスレッドのデバッガで待機しているように見えます)。これは、あなたのロックが長期間保持されていることを示唆しています。同時実行を効果的に使用したい場合は、短期間だけロックを保持してください。

+0

ありがとう、ジャスティン!はい、そうです、このデリゲートメソッドはロックを使用している別のスレッドを呼び出します。 @synchronized(someVariable)に変更しましたが、部分的に解決されたようですが、しばらくしています。 –

+0

それは正しい解決策ではありません、問題を無視してください。下の私の答えを見てください。 – Antigluk

+0

@igelekle ok - スレッドセーフな状態で、(co)依存関係をどのように破ることができるかを理解してください。ロックを長時間保持することも避けなければならない。細かい点を調整することも、(あなたが試みたように、アップデートの様子から)大量のデータを保護する大きなロックは、しばしばキラーです(小さすぎるものも多すぎます)。 – justin

3

クラスのデザインをほとんど見直さないといけません。それは起こるべきではありません。 その場合、インスタンスをロックするクリティカルセクション(synchronized())を見てください。それらのうちの1つはインスタンスを永遠にロックします。または、多分、クロスロック(方法M1はAをロックし、方法M2はBをロックし、同時にロックを交換したい)の場合、デッドロックが発生する可能性があります。

+0

ありがとう!私は機能を再設計する必要があります。 –

関連する問題