美文网首页iOSiOS面试ios-多线程
递归锁 NSRecursiveLock -trylock

递归锁 NSRecursiveLock -trylock

作者: 迷路卜 | 来源:发表于2018-02-25 17:10 被阅读2次

关于 NSRecursiveLock trylock 认知版本

错误的认知:

1.0

以为 trylock 是一个安全校验 如果返回NO时 调用 lock 会出问题

2.0

以为 trylock 是如果线程中有锁 就返回 YES 并调用 lock 上锁,反之返回NO 不做任何操作

正确的认知:

3.0

  • 在同一个线程中多次 lock 不会造成死锁 但是可能会造成线程等待

  • 如果锁在 线程A 中 lock 了 并没有解锁, 那么在其他线程如果调用了该锁(除trylock外)的方法就会造成 该线程的等待,直到 线程A的锁unlock

  • 如果锁在 线程A 中 lock 了 并没有解锁, 在线程A中 trylock 返回 YES ,并再 lock 一次,此时需要增加 unlock 操作

  • 如果锁在 线程A 中 lock 了 并没有解锁,在其他线程 trylock 返回NO , 如果这个线程没有调用 lock 方法 即 只调用trylock 或者 unlock 方法, 不会造成线程等待,该线程的任务会继续走下去, 造成没有 lock 的现象

trylock 的应用场景

trylock 的唯一的特性就是 不会阻塞线程 也就是说如果 线程A中 lock 了,但是在线程B 中可以不管锁是不是上锁状态,直接执行,此时可以用 trylock

测试代码:


@interface LockViewController ()
@property(nonatomic, strong) NSRecursiveLock *myLock;
@end
@implementation LockViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _myLock = [[NSRecursiveLock alloc] init];
    [self testBlock];
}
    //加锁
- (void)lock {
    if ([_myLock tryLock]) {
        NSLog(@"%@ try lock ",[NSThread currentThread]);
        return;
    } else{
        NSLog(@"%@ try lock fail",[NSThread currentThread]);
    }
    NSLog(@"%@  lock",[NSThread currentThread]);
    [_myLock lock];
}
    //解锁
-(void)unlock {
    NSLog(@"%@  unlock",[NSThread currentThread]);
    [_myLock unlock];
}
- (void)testBlock{
    dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
        NSThread *thread = [NSThread currentThread];
        thread.name = @"add";
        for (int i = 0; i < 2; i++) {
            [self lock];
            NSLog(@"%@  add ",[NSThread currentThread]);
            [self unlock];
        }
    });
    dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
        NSThread *thread = [NSThread currentThread];
        thread.name = @"remove";
        for (int i = 0; i < 1; i++) {
            sleep(3);
            if ([_myLock tryLock]) {
                NSLog(@"%@   remove",[NSThread currentThread]);
            };
        }
    });
}

调试辅助代码,给NSRecursiveLock增加了一个类目用runtime截获 lock 和unlock 方法 打印日志:

+(void)load {
    
    Method lock = class_getInstanceMethod(self, @selector(lock));
    Method testLock = class_getInstanceMethod(self, @selector(testLock));
    method_exchangeImplementations(lock, testLock);
    
    Method unlock = class_getInstanceMethod(self, @selector(unlock));
    Method testUnLock = class_getInstanceMethod(self, @selector(testUnlock));
    method_exchangeImplementations(unlock, testUnLock);
}

- (void)testLock{
    [self testLock];
    NSLog(@"testLock +++++ ");
}

- (void)testUnlock {
    [self testUnlock];
     NSLog(@"testUnlock +++++ ");
}

相关文章

  • 递归锁 NSRecursiveLock -trylock

    关于 NSRecursiveLock trylock 认知版本 错误的认知: 1.0 以为 trylock 是...

  • iOS中锁的种类

    NSRecursiveLock递归锁NSRecursiveLock实际上定义的是一个递归锁,这个锁可以被同一线程多...

  • 013-iOS锁机制

    锁的类别 NSLockingNSLockNSConditionLock 条件锁NSRecursiveLock 递归...

  • 线程锁

    iOS中有几种线程锁:@synchronized、NSLock以及NSRecursiveLock(递归锁)。本文用...

  • NSRecursiveLock递归锁

    递归锁,它允许同一线程多次加锁,而不会造成死锁。以下的代码如果用NSLock就会造成死锁: //普通线程锁NSLo...

  • Swift - 锁

    NSLock NSRecursiveLock 递归锁 当发生自己调用自己的时候,或者递归的时候,需要使用递归锁NS...

  • iOS -锁-NSRecursiveLock

    NSRecursiveLock,递归锁,顾名思义,执行递归操作的时候使用的锁。是互斥锁中的递归锁,可被同一线程多次...

  • 线程锁

    @synchronized 是递归锁,类似NSRecursiveLock,递归调用不会引起死锁,而NSLock是非...

  • 多线程 — 锁

    互斥锁 NSLock 加锁之后在解锁之前,资源独占其他人不能访问 递归锁 NSRecursiveLock 同一线程...

  • iOS锁系列-NSRecursiveLock递归锁

    原文,此文只为总结学习使用NSRecursiveLock实际上定义的是一个递归锁,这个锁可以被同一线程多次请求,而...

网友评论

    本文标题:递归锁 NSRecursiveLock -trylock

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