13

我猜@synchronized 块不依赖于对象,而是依赖于线程......对吗?在那种情况下,我们为什么要通过 self?

4

3 回答 3

21

@synchronized是语言提供的用于创建同步作用域的构造。由于使用简单的全局共享互斥锁会非常低效,因此会序列化@synchronized应用程序中的每一个作用域,该语言允许我们指定一个同步点。

然后由开发人员决定哪些同步点适合该任务。

在实例方法上,使用 self 很常见:实例是同步点。@synchronized(self)范围可以在任意数量的实例上调用,但对于给定的实例只能调用一次。每个@synchronized(self)范围都将针对给定的实例进行序列化。

当然,如果您愿意,您可以随意使用另一个同步点。您可以使用类 ( @synchronized(self.class)) 或任何其他适合您需要的东西。

于 2012-07-26T09:33:25.287 回答
5

我质疑这种做法,因为它是其他语言中已知的反模式。问题的关键是其他人也可能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];
于 2015-03-23T18:54:17.323 回答
4

传入的对象用于区分哪些@synchronized块对应锁定。使用self通常很方便,但如果您只想同步更小、更具体的代码部分(例如,同步对特定 的所有访问NSMutableDictionary,而不是同步整个实例中的所有内容) ,有时使用其他对象是个好主意

我不确定您所说的“线程依赖”是什么意思。的目的@synchronized是用于可能在不同线程上运行的代码块,并且您需要确保任何时候只运行 1 个,而不会重叠。对于执行非线程安全的操作很重要(例如,改变集合)。

于 2012-07-26T09:27:29.200 回答