我猜@synchronized块不是基于对象而是基于线程的...对吗?如果是这样,为什么要传递self?
我猜@synchronized块不是基于对象而是基于线程的...对吗?如果是这样,为什么要传递self?
@synchronized
是一种语言提供的构造,用于创建同步作用域。由于使用简单的全局共享互斥锁会非常低效,从而使应用程序中的每个@synchronized
作用域都被序列化,因此语言允许我们指定同步点。
然后开发人员可以决定哪些同步点适合完成任务。
在实例方法中,使用self是常见的:实例是同步点。 @synchronized(self)
作用域可以在任意数量的实例上调用,但对于给定的实例只能调用一次。对于给定实例,每个@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个且不重叠。这对于执行不支持线程安全的操作(例如改变集合等)非常重要。