美文网首页
iOS锁的基本使用

iOS锁的基本使用

作者: 瀚_ | 来源:发表于2019-08-16 18:03 被阅读0次

    @synchronized

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            NSLog(@"线程1 开始");
            @synchronized (self) {
                sleep(3);
                NSLog(@"线程1 结束");
            }
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            NSLog(@"线程2 开始");
            @synchronized (self) {
                sleep(1);
                NSLog(@"线程2 结束");
            }
    });
    

    dispatch_semaphore

    dispatch_semaphore_t signal = dispatch_semaphore_create(1);
    dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        dispatch_semaphore_wait(signal, overTime);
        NSLog(@"线程1 开始");
        sleep(2);
        NSLog(@"线程1 结束");
        dispatch_semaphore_signal(signal); 
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        dispatch_semaphore_wait(signal, overTime);
        NSLog(@"线程2 开始");
        sleep(1);
        NSLog(@"线程2 结束");
        dispatch_semaphore_signal(signal);    
    });
    
    • dispatch_semaphore_wait 会使信号量减1,如果信号量的值小于0,就阻塞当前线程直到超时才继续执行。
    • dispatch_semaphore_signal 使信号量加1,如果之前的信号量小于0,那么会唤醒正在由dispatch_semaphore_wait等待的线程。

    NSLock

    NSLock *lock = [[NSLock alloc] init];
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        [lock lock];
        NSLog(@"线程1 开始");
        sleep(2);
        NSLog(@"线程1 结束");
        [lock unlock];
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        if ([lock tryLock]) {
             NSLog(@"锁可用");
            [lock unlock];
        }
        else {
            NSLog(@"锁不可用");
        }
            
        NSDate *date = [NSDate dateWithTimeIntervalSinceNow:3];
        if ([lock lockBeforeDate:date]) {
            NSLog(@"没有超时, 获得锁");
            [lock unlock];
        }
        else {
            NSLog(@"超时, 没有获得锁");
        }
    });
    

    NSRecursiveLock

    NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
      
    __block int value = 5;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        static void(^RecursiveMethod)(void);
            
        RecursiveMethod = ^(void) {
                
            [lock lock];
            if (value > 0) {
                NSLog(@"线程1  value = %d", value);
                value -= 1;
                sleep(1);
                RecursiveMethod();
            }
            [lock unlock];
        };
            
        RecursiveMethod();
            
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        [lock lock];
        NSLog(@"线程2  value = %d", value);
        [lock unlock];
    });
    

    NSConditionLock

    NSMutableArray *products = [NSMutableArray arrayWithArray:@[@"1", @"2", @"3"]];
        
    NSInteger beginProduct = 1;     // 开始生产, 停止消费
    NSInteger haltProduct = 0;      // 停止生产, 开始消费
        
    NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:beginProduct];
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        while (1) {
            [lock lockWhenCondition:beginProduct];
            [products addObject:@"1"];
            NSLog(@"生产了一个产品, 总量: %zi", products.count);
            NSInteger status = products.count > 10 ? haltProduct : beginProduct;
            [lock unlockWithCondition:status];
            sleep(5);
        }   
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
        while (1) {
            [lock lockWhenCondition:haltProduct];
            [products removeObjectAtIndex:0];
            NSLog(@"消费了一个产品, 总量: %zi", products.count);
            NSInteger status = products.count < 3 ? beginProduct : haltProduct;
            [lock unlockWithCondition:status];  
            sleep(3);
        }
    });
    

    NSCondition

    NSCondition *condition = [[NSCondition alloc] init];
        
    NSMutableArray *products = [NSMutableArray array];
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        while (1) {
            [condition lock];
            if (products.count == 0) {
                NSLog(@"等待生产");
                [condition wait];
            }
            [products removeObjectAtIndex:0];
            NSLog(@"消费了一个产品, 总量: %zi", products.count);
            [condition unlock];
            sleep(2);
        }
            
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        while (1) {
            [condition lock];
            [products addObject:@"1"];
            NSLog(@"生产了一个产品, 总量: %zi", products.count);
            if (products.count > 5) {
                [condition signal];
            }
            [condition unlock];
            sleep(3);
        }
    });
    

    pthread_mutex

    static pthread_mutex_t lock;
        
    pthread_mutex_init(&lock, NULL);
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        pthread_mutex_lock(&lock);
        NSLog(@"线程1 开始");
        sleep(3);
        NSLog(@"线程1 结束");
        pthread_mutex_unlock(&lock);
            
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        pthread_mutex_lock(&lock);
        NSLog(@"线程2 开始");
        sleep(3);
        NSLog(@"线程2 结束");
        pthread_mutex_unlock(&lock);
    });
    

    pthread_mutex(recursive)

    static pthread_mutex_t lock;
        
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&lock, &attr);
    pthread_mutexattr_destroy(&attr);
        
    __block int value = 5;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        static void(^RecursiveMethod)(void);
            
        RecursiveMethod = ^{
                
            pthread_mutex_lock(&lock);
            if (value > 0) {
                NSLog(@"线程1 value = %d", value);
                value -= 1;
                sleep(2);
                RecursiveMethod();
            }
            pthread_mutex_unlock(&lock);
        };
            
        RecursiveMethod();
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        pthread_mutex_lock(&lock);
        NSLog(@"线程2 value = %d", value);
        pthread_mutex_unlock(&lock);
    });
    

    OSSpinLock

    static OSSpinLock lock = OS_SPINLOCK_INIT;
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        OSSpinLockLock(&lock);
        NSLog(@"线程1 开始");
        sleep(3);
        NSLog(@"线程1 结束");
        OSSpinLockUnlock(&lock);
    });
        
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
        OSSpinLockLock(&lock);
        NSLog(@"线程2 开始");
        sleep(3);
        NSLog(@"线程2 结束");
        OSSpinLockUnlock(&lock);
    });
    

    os_unfair_lock

    if (@available(iOS 10.0, *)) {
        static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
            
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                
            os_unfair_lock_lock(&lock);
            NSLog(@"线程1 开始");
            sleep(3);
            NSLog(@"线程1 结束");
            os_unfair_lock_unlock(&lock);
        });
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                
            os_unfair_lock_lock(&lock);
            NSLog(@"线程2 开始");
            sleep(3);
            NSLog(@"线程2 结束");
            os_unfair_lock_unlock(&lock);
        });
            
    }
    

    参考资料

    iOS中保证线程安全的几种方式与性能对比

    相关文章

      网友评论

          本文标题:iOS锁的基本使用

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