2

あなたが言う

MyLock *lock = [[MyLock new] autorelease];
@synchronized(lock) {
    NSLog(@"Hello World");
//some very long process
}

メインスレッドで。それは、//非常に長いプロセスが完了するまで、メイン スレッドがロックされることを意味しますか? 他のスレッドが呼び出された場合

    //Update on the main thread
    dispatch_sync(dispatch_get_main_queue(), ^{
        //Do some updates
    });

いくつかの更新が呼び出されないということですか? 私は正しいですか?

4

2 に答える 2

6

最初のコード スニペットのコードが終了しない場合、@synchronizedステートメントに関係なく、2 番目のコード スニペットは呼び出されません。スレッドは、実行中のコードによってブロックされています。このステートメントは、複数の@synchronizedスレッド間でデータ アクセスを同期するためのものであり、有用であるためには、参加しているすべてのスレッドが実際にステートメントを使用する必要があります。参加しているすべてのスレッドが「同意」しない限り、データ構造へのアクセスを「魔法のように」ロックすることはありません。

@synchronizedとにかく、特定の(単一の)スレッドで1つのメソッドのみが実行されるようにするために使用しません。

その使用の具体的な例を示すNSMutableArrayために、異なるスレッドから同時に変更されないように保護したい (データの破損につながる可能性がある) があるとします。その場合、@synchronized同じロックトークンを持つブロックで常にアクセスできます。

例:

//Thread 1:
@synchronized (myArray) {
    [myArray addObject:@"foo"];
}

//Thread 2:
@synchronized (myArray) {
    [myArray removeObjectAtIndex:0];
}

これにより、 で囲まれたコード ブロックが@synchronized同時に実行されなくなります。1 つのスレッドがブロックに入ると、他のスレッドはそれが終了するまで待機しますが、同じステートメントを使用している場合に限ります。@synchronizedあるスレッドで使用するのを忘れた場合、別のスレッドで使用してもまったく役に立ちません。

于 2012-05-21T09:44:44.863 に答える
1

短い答えはノーです。ロックの概念を理解していないと思います。たとえば、ここで同期の詳細を読む必要があります。

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

保護しようとしているコードにアクセスするときは、常に同じロック オブジェクト (同じインスタンス!) を使用して同期する必要があります。ロックオブジェクトをクラスのプロパティとして保存できます。

あなたの場合:

self.lock = [[MyLock new] autorelease]; //in init method initialize retain or strong lock property

...
@synchronized(self.lock) {
   NSLog(@"Hello World");
   //some very long process
}


//Update on the main thread
dispatch_sync(dispatch_get_main_queue(), ^{
   @synchronized(self.lock) {
      NSLog(@"Hello World");
      //some very long process
   }
});

ロックオブジェクトとして使用できる場合は、保護しようとしているオブジェクト。

于 2012-05-21T09:44:56.133 に答える