@interface ViewController ()
@end
@implementation ViewController {
NSCondition *_condition; //线程控制
NSMutableArray *_arr; //待处理的对象集合
}
- (void)viewDidLoad {
[super viewDidLoad];
_condition = [[NSCondition alloc] init];
_arr = [NSMutableArray arrayWithObjects:@1,@2,@3,@4,@5,@6,@7,@8,@9,nil]; //内置9个对象
}
//随便创建一个按钮
- (IBAction)lockBtn:(id)sender {
dispatch_queue_t group_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(group_queue, ^{
//线程任务加锁
NSLog(@"加锁");
[_condition lock];
//处理所有对象.只要当前对象集合不为0,未处理完毕
while (_arr.count != 0) {
[_arr removeObjectAtIndex:0];//处理第一个对象.
NSLog(@"%@",_arr);
//这里做对象处理的操作,计算,上传,删除等等的耗时操作.其的对象等待当前对象完成
[_condition wait];
}
NSLog(@"解锁");
[_condition unlock];
});
}
//随便创建一个按钮
- (IBAction)removeObjBtn:(id)sender {
dispatch_queue_t group_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(group_queue, ^{
[_arr removeObjectAtIndex:1]; //随便做一个对象资源删除操作.
NSLog(@"%@",_arr);
});
}
//随便创建一个按钮
- (IBAction)unlockBtn:(id)sender {
dispatch_queue_t group_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(group_queue, ^{
NSLog(@"%@",[NSThread currentThread]);
[_condition lock];
[_condition signal];
[_condition unlock];
});
}
@end
关于NSCondition
概述 : 条件对象在给定线程中充当锁和检查点。锁在测试条件时保护您的代码并执行由条件触发的任务。检查点行为要求在线程继续其任务之前条件为真。虽然条件不成立,线程块。直到另一个线程发送条件对象时,它才会被阻塞。
内部方法
NS_CLASS_AVAILABLE(10_5, 2_0)
@interface NSCondition : NSObject <NSLocking> {
@private
void *_priv;
}
- (void)wait; //无限时等待
- (BOOL)waitUntilDate:(NSDate *)limit; //限时等待
- (void)signal; //释放某一线程的等待事件
- (void)broadcast; //广播所有线程释放当前的等待事件
@property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
@end
signal :
指示条件,唤醒一个等待它的线程。
您使用此方法唤醒正在等待条件的一个线程。 您可能会多次调用此方法来唤醒多个线程。 如果没有线程在等待条件,这个方法什么也不做。
为了避免竞争条件,只有在接收器被锁定的情况下才应该调用这个方法。
broadcast :
指示条件,唤醒等待它的所有线程。
如果没有线程在等待条件,这个方法什么也不做。
为了避免竞争条件,只有在接收器被锁定的情况下才应该调用这个方法。
理解 :
- 上面的例子中用的只有一个全局并发队列,所以总的来说只有一个线程.所以signal和broadcast的方法的效果是一样的.
- 如果有多个线程.每个线程里面有多个等待时间.那么signal会释放任意一个等待. 而broadcast会释放所有线程的当前的等待事件.也就是一个线程内有多个等待事件就释放最前面的一个.
网友评论