iOS中的线程锁(关于NSCondition)

278 阅读2分钟

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

NSCondition(条件锁)

NSCondition 概念

NSCondition 封装了一个互斥锁和条件变量。互斥锁保证线程安全,条件变量保证执行顺序。

NSCondition 常用方法 <遵守 NSLocking 协议>

- (void)lock;             //加锁
- (void)unlock;           //解锁
- (void)wait;             //让当前线程处于等待状态
- (void)signal;           //CPU发信号告诉线程不用在等待,可以继续执行
- (void)broadcast;        //唤醒等待的所有线程

NSCondition 常用场景

使用 NSCondition 能够解决线程的生产者消费者问题

基本思路是:

  1. 创建 NSCondition 实例,并创建消费者和生产者

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.condition = [[NSCondition alloc]init];
        self.productCount = 0;
        
        
        //创建俩个消费者
        for (int i=0; i<2; i++) {
            NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(createConsumenr) object:nil];
            thread.name = [NSString stringWithFormat:@"第%d个消费者",i];
            [thread start];
        }
        
        //创建俩个生产者
        for (int i=0; i<2; i++) {
            NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(createProducter) object:nil];
            thread.name = [NSString stringWithFormat:@"第%d个生产者",i];
            [thread start];
        }
    }
        ```
    
    
  2. 消费者购买商品,首先进行加锁,购买产品,如果目前没有该商品,则进入 wait 状态,直到有线程唤醒它去购买商品,最后再进行解锁 unlock

    - (void)createConsumenr{
        NSLog(@"%@:准备购买商品",[NSThread currentThread].name);
        [self.condition lock];
        
        while (self.productCount == 0) {
            NSLog(@"%@:等待产出商品",[NSThread currentThread].name);
            [self.condition wait];
        }
        NSLog(@"%@:已经购买商品",[NSThread currentThread].name);
        self.productCount = self.productCount - 1;
        
        [self.condition unlock];
    }
    
  3. 生产者生产商品。首先进行加锁,然后再生产,生产完毕之后,cpu发出 signal 消息,这样可以唤醒 wait 的购买线程,最后再进行解锁 unlock

    - (void)createProducter{
        [NSThread sleepForTimeInterval:1];
        
        [self.condition lock];
        
        NSLog(@"%@:生产商品",[NSThread currentThread].name);
        self.productCount = self.productCount + 1;
        NSLog(@"%@:生产完毕了",[NSThread currentThread].name);
        
        //此方法能够唤醒一个等待中的线程,如果有多个线程在等待,随机唤醒一个
        [self.condition signal];
        
        [self.condition unlock];
    }
    

    log:

    Snip20211116_18.png