为什么我们在@synchronized块中传递self?

Adv*_*ith 13 macos synchronization block objective-c ios

我想@synchronized块不依赖于对象,但依赖于线程......对吗?在那种情况下,为什么我们通过自我?

fab*_*ier 21

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

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

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

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

  • 谢谢!我需要确切知道@synchronized(self)与@synchronized(self.class)有什么不同?我从你的语句中理解的是,当我们用@synchronized(self)锁定一个块时,它确保没有两个线程会对一个对象运行该块.当我们使用@synchronized(self.class)时,它将确保没有两个线程将针对该类的任何对象运行该块.我对么? (5认同)

Oha*_*der 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];
Run Code Online (Sandbox Code Playgroud)