最近再看parse 代码 发现了一块给task 队列加锁的用法部分。
场景一
synchronized是使用的递归mutex来做同步。例如:
@synchronized (obj) {
NSLog(@"1st sync");
@synchronized (obj) {
NSLog(@"2nd sync");
}
}
场景二
@synchronized(nil)不起任何作用
场景三
- (void)synchronizedAMethod {
@synchronized (self) {
//Safe
}
}
- (void)synchronizedBMethod {
@synchronized (self) {
//Safe
}
}
- (void)synchronizedCMethod {
@synchronized (self) {
//Safe
}
}
如果正在执行synchronizedAMethod 方法 此synchronizedBMethod和synchronizedCMethod 需要等待前面的方法结束才能执行。
场景四
NSObject *obj = [[NSObject alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self) {
NSLog(@"需要线程同步的操作1 开始");
sleep(3);
NSLog(@"需要线程同步的操作1 结束");
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
@synchronized(obj) {
NSLog(@"需要线程同步的操作2");
}
});
需要线程同步的操作1 开始
需要线程同步的操作2
需要线程同步的操作1 结束
如果都是key 都是self 那么
需要线程同步的操作1 开始
需要线程同步的操作1 结束
需要线程同步的操作2
总结
synchronized中传入的object的内存地址,被用作key,通过hash map对应的一个系统维护的递归锁。
如果object 被外部访问变化,则就失去了锁的作用。所以最好本类声明一个对象属性来当做key
参考
网友评论