@synchronized ブロックはオブジェクト依存ではなく、スレッド依存だと思います...そうですか?その場合、なぜ自分自身を渡すのでしょうか?
3 に答える
@synchronized
同期スコープを作成するために言語によって提供される構造です。単純なグローバル共有ミューテックスを使用@synchronized
してアプリケーション内のすべてのスコープをシリアル化するのは非常に非効率的であるため、この言語では同期ポイントを指定できます。
次に、タスクに適した同期ポイントを決定するのは開発者次第です。
インスタンス メソッドでは、self を使用するのが一般的です。インスタンスが同期ポイントです。スコープは任意の@synchronized(self)
数のインスタンスで呼び出すことができますが、特定のインスタンスに対して 1 回だけです。すべての@synchronized(self)
スコープは、特定のインスタンスに対してシリアル化されます。
もちろん、必要に応じて別の同期ポイントを自由に使用できます。クラス ( @synchronized(self.class)
) または必要に応じて他のものを使用できます。
他の言語ではアンチパターンとして知られているので、私はこのやり方に疑問を持っています。問題の核心は、synchronize
ロックにプライベート NSObject を使用していた場合には存在しなかったデッドロックやその他の問題が発生する可能性があることです。例えば:
@implementation foo
-(void) bar
{
@synchronized(self) {
@synchronized(sharedLock) {
//do something
}
}
}
Foo* foo = [[Foo alloc] init];
@synchronized(sharedLock) {
@synchronized(foo) {
//do something
}
}
//in another thread
[foo bar];
渡されたオブジェクトは、どの@synchronized
ブロックが相互のロックに対応するかを区別するために使用されます。を使用するself
と便利なことがよくありますが、より小さく、より具体的なコードのセクションのみを同期する場合は、他のオブジェクトを使用することをお勧めします (たとえばNSMutableDictionary
、インスタンス全体のすべてを同期するのではなく、特定の へのすべてのアクセスを同期します) 。
「スレッド依存」の意味がわかりません。の目的は@synchronized
、異なるスレッドで実行される可能性のあるコードのブロックのためであり、重複することなく、常に 1 つの実行のみを保証する必要があります。スレッドセーフではないアクションを実行する場合に重要です (たとえば、コレクションの変更など)。