@synchronized不使用“lock”和“unlock”实现互斥吗?那么它是如何锁定/解锁的呢?
下面程序的输出仅仅是“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];
}
Objective-C语言级别的同步使用互斥锁,就像NSLock一样。语义上存在一些小的技术差异,但将它们视为在一个公共(更原始)实体之上实现的两个独立接口基本上是正确的。
特别是使用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;
}
这不是完全正确的,因为实际的转换更复杂,并且使用递归锁,但它应该能够理解这一点。
Objective-C语言级别的同步使用互斥锁,就像NSLock一样。语义上存在一些小的技术差异,但将它们视为在一个公共(更原始)实体之上实现的两个独立接口基本上是正确的。
特别是使用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;
}
这不是完全正确的,因为实际的转换更复杂,并且使用递归锁,但它应该能够理解这一点。