美文网首页
NSCondition处理线程控制

NSCondition处理线程控制

作者: li_礼光 | 来源:发表于2018-02-01 11:20 被阅读26次
@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会释放所有线程的当前的等待事件.也就是一个线程内有多个等待事件就释放最前面的一个.

相关文章

网友评论

      本文标题:NSCondition处理线程控制

      本文链接:https://www.haomeiwen.com/subject/rgxdzxtx.html