说你做
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
});
永远不会调用某些更新?我是对的吗?
答案 0 :(得分:6)
如果第一个代码段中的代码永远不会完成,则无论@synchronized
语句如何,都不会调用第二个代码。线程被您正在执行的代码阻止。 @synchronized
语句用于同步多个线程之间的数据访问并且有用,它要求所有参与的线程实际使用该语句。它不会“神奇地”锁定对数据结构的访问,除非所有参与的线程都“同意”它。
您不使用@synchronized
来确保在给定(单个)线程上只执行一个方法,无论如何都是如此。
为了给你一个使用它的具体例子,假设你有一个NSMutableArray
你想要防止同时从不同的线程修改(这可能导致数据损坏)。在这种情况下,您始终可以使用相同的锁定令牌在@synchronized
块中访问它。
示例:
//Thread 1:
@synchronized (myArray) {
[myArray addObject:@"foo"];
}
//Thread 2:
@synchronized (myArray) {
[myArray removeObjectAtIndex:0];
}
这将确保@synchronized
所包含的代码块永远不会同时执行。当一个线程进入该块时,其他线程一直等到它完成,但仅当时它们也使用相同的@synchronized
语句。如果你忘记在一个线程上使用它,如果你在另一个线程上使用它,它根本没用。
答案 1 :(得分:1)
简短的回答是否定的。我认为你不理解锁定的概念。您应该阅读有关同步化的更多信息,例如:
当您访问要保护的代码时,必须在每种情况下使用相同的锁定对象(相同的实例!)进行同步。您可以将锁定对象存储为类的属性。
在你的情况下:
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
}
});
如果您可以使用您想要保护的对象作为锁定对象。