问题:
Does @synchronized not use "lock" and "unlock" to achieve mutual exclusion? How does it dolock/unlock then?
The output of the following program is only "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];
}
回答:
The objective C language level synchronization uses the mutex, just like NSLock does. Semantically there are some small technical differences, but it is basically correct to think of them as two seperate interface implemented on top of a common (more primitive) entity.
In particular with an NSLock you have an explicit lock whereas with @synchronize you have an implicitlock associated with the object you are using to synchronize. The benefit of the language level locking is the compiler understands it so it can deal with scoping issues, but mechanically they are the behave basically the same.
You can think of @synchronize as basically a compiler rewrite:
- (NSString *)myString {
@synchronized(self) {
return [[myString retain] autorelease];
}
}
is transformed into:
- (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;
}
That is not exactly correct because the actual transform is more complex and uses recursive locks, but it should get the point across.
本文深入探讨了Objective-C中@synchronized指令的工作原理,通过对比NSLock的显式锁操作,解释了语言级同步如何利用互斥锁实现。并提供了一个具体的代码示例,展示了@synchronized如何隐式地对指定对象进行加锁和解锁。

被折叠的 条评论
为什么被折叠?



