@synchronized是否不使用“锁定”和“解锁”来实现互斥?那么它如何锁定/解锁?

以下程序的输出仅是“Hello World”。

@interface MyLock: NSLock<NSLocking>
@end

@implementation MyLock

- (id)init {
    return [super init];
}

- (void)lock {
    NSLog(@"before lock");
    [super lock];
    NSLog(@"after lock");
}

- (void)unlock {
    NSLog(@"before unlock");
    [super unlock];
    NSLog(@"after unlock");
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    MyLock *lock = [[MyLock new] autorelease];
    @synchronized(lock) {
        NSLog(@"Hello World");
    }

    [pool drain];
}

最佳答案

NSLock一样,Objective-C语言级同步也使用互斥量。从语义上讲,存在一些小的技术差异,但是将它们视为在一个共同的(更原始的)实体之上实现的两个单独的接口(interface),基本上是正确的。

特别是对于NSLock,您具有显式锁,而对于@synchronized,您具有与要用于同步的对象相关联的隐式锁。语言级别锁定的好处是编译器可以理解它,因此它可以处理范围界定问题,但是从机械上讲,它们的行为基本相同。

您可以将@synchronized视为编译器重写:

- (NSString *)myString {
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

转换为:
- (NSString *)myString {
  NSString *retval = nil;
  pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
  pthread_mutex_lock(self_mutex);
  retval = [[myString retain] autorelease];
  pthread_mutex_unlock(self_mutex);
  return retval;
}

这并不完全正确,因为实际的转换更加复杂并且使用了递归锁,但是应该可以理解这一点。

10-07 16:35
查看更多