我认为@synchronized块不依赖于对象但依赖于线程......对吗?在那种情况下,我们为什么要通过自我?
答案 0 :(得分:20)
@synchronized
是由语言提供的用于创建同步范围的构造。由于使用简单的全局共享互斥锁并因此序列化应用程序中的每个@synchronized
范围非常低效,因此该语言允许我们指定同步点。
然后由开发人员决定哪个同步点适合该任务。
在实例方法中,使用self很常见:实例是同步点。 @synchronized(self)
范围可以在任意数量的实例上调用,但对于给定的实例只能调用一次。每个@synchronized(self)
范围都将针对给定实例进行序列化。
当然,如果您愿意,可以自由使用其他同步点。您可以使用课程(@synchronized(self.class)
)或其他任何符合您需求的内容。
答案 1 :(得分:4)
传入的对象用于区分哪些@synchronized
块对应于相互锁定。使用self
通常很方便,但如果您只想同步更小,更具体的代码部分(例如,同步对特定NSMutableDictionary
的所有访问),则有时使用其他对象是个好主意。而不是同步整个实例中的所有内容)
我不确定“线程依赖”是什么意思。 @synchronized
的目的是用于可能在不同线程上运行的代码块,并且您需要确保在任何时间只运行1次而不重叠。对于执行非线程安全的操作很重要(例如,变异集合)。
答案 2 :(得分:4)
我质疑这种做法,因为它是known anti-pattern in other languages。问题的关键在于,其他人也可以在您的对象上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];