4. 条件锁
4.1 NSCondition
NSCondition 的对象实际上是作为一个锁和线程检查器,锁主要是为了检测条件时保护数据源,执行条件引发的任务。线程检查器主要是根据条件决定是否继续运行线程,即线程是否被阻塞。
NSCondition同样实现了NSLocking协议,所以它和NSLock一样,也有NSLocking协议的lock和unlock方法,可以当做NSLock来使用解决线程同步问题,用法完全一样。
- (NSMutableArray *)removeLastImageNSMutableArray *)images {
if (images.count > 0) {
NSCondition *condition = [[NSCondition alloc] init];
[condition lock];
[images removeLastObject];
[condition unlock];
NSLog(@"removeLastImage %@",images);
return images;
}else{
return NULL;
}
}
复制代码
同时,NSCondition提供更高级的用法。wait和signal,和条件信号量类似。
NSCondition和NSLock、@synchronized等是不同的是,NSCondition可以给每个线程分别加锁,加锁后不影响其他线程进入临界区。这是非常强大。
- (void)lock10 {
self.conditionArray = [NSMutableArray array];
self.xwCondition = [[NSCondition alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.xwCondition lock];
if (self.conditionArray.count == 0) {
NSLog(@"等待制作数组");
[self.xwCondition wait];
}
id obj = self.conditionArray[0];
NSLog(@"获取对象进行操作:%@",obj);
[self.xwCondition unlock];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.xwCondition lock];
id obj = @"极客学伟";
[self.conditionArray addObjectbj];
NSLog(@"创建了一个对象:%@",obj);
[self.xwCondition signal];
[self.xwCondition unlock];
});
}
复制代码
4.2 NSConditionLock
- (void)lock11 {
NSConditionLock *conditionLock = [[NSConditionLock alloc] init];
NSMutableArray *arrayM = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[conditionLock lock];
for (int i = 0; i < 6; i++) {
[arrayM addObject(i)];
NSLog(@"异步下载第 %d 张图片",i);
sleep(1);
if (arrayM.count == 4) {
[conditionLock unlockWithCondition:4];
}
}
});
dispatch_async(dispatch_get_main_queue(), ^{
[conditionLock lockWhenCondition:4];
NSLog(@"已经获取到4张图片->主线程渲染");
[conditionLock unlock];
});
}
复制代码
4.2 pthread POSIX Conditions
- (void)lock12 {
__block pthread_mutex_t mutex;
__block pthread_cond_t condition;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condition, NULL);
NSMutableArray *arrayM = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&mutex);
for (int i = 0; i < 6; i++) {
[arrayM addObject(i)];
NSLog(@"异步下载第 %d 张图片",i);
sleep(1);
if (arrayM.count == 4) {
pthread_cond_signal(&condition);
}
}
});
dispatch_async(dispatch_get_main_queue(), ^{
pthread_cond_wait(&condition, &mutex);
NSLog(@"已经获取到4张图片->主线程渲染");
pthread_mutex_unlock(&mutex);
});
} |