iOS锁的基本使用

2019-08-16  本文已影响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);    
});

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中保证线程安全的几种方式与性能对比

上一篇下一篇

猜你喜欢

热点阅读