美文网首页线程锁线程安全
NSLock, NSRecursiveLock

NSLock, NSRecursiveLock

作者: 谌文 | 来源:发表于2020-01-14 01:05 被阅读0次

NSLock

这是一个低级别的锁。一旦获取锁,执行则进入临界区,且不会允许超过一个线程并行执行。释放锁则标记临界区的结束。

例 展示啦如何使用NSLock

@interface ThreadSafeClass ()
{
    NSLock *lock;
}
@end

- (instancetype)init {
    if (self = [super init]) {
        self->lock = [NSLock new];
    }
    return self;
}
- (void)safeMehod {
    [self->lock lock];
    /// 线程安全代码 2
    [self->lock unlock];
}
  • 讲锁声明为一个私有的字段,也可以用属性来表示锁。
  • 初始化锁
  • 获取锁,进入临界区
  • 在临界区,任意时刻最多只允许一个线程执行
  • 释放锁标记着临界区的结束。其他线程现在能够获取锁了。

疑问:

1 为啥 NSLock必须在锁定的线程中进行解锁。
2 当 /// 线程安全代码 2中调用类中其他方法,其他方法也要加锁怎么办?。 重用[self->lock lock]; [self->lock unlock];?? 这是不行的,使用释放锁才能加加锁,一一对应的,那怎么办呢,接下来看下面这个文章

    [self->lock lock];
    /// 线程安全代码 2
    [self->lock unlock];

如以下只会打印0,1,

- (void)safeMehod {
    NSLog(@"0");
    [self->lock lock];
    NSLog(@"1");

    [self->lock lock];
    NSLog(@"2");

    /// 线程安全代码
    [self->lock unlock];
    NSLog(@"3");
}

NSRecursiveLock

在调用lock之前,NSLock必须先调用unlock。但正如名字所暗示的那样,
NSRecursiveLock允许在被解锁之前锁定多次。如果解锁次数与锁定的次数相匹配,则认为锁被释放,其他线程可以获取锁。
当类中有多个方法使用同一个锁进行同步时,且其中一个方法调用另一个方法时,NSRecursiveLock非常有用,例4-6展示了使用NSRecursiveLock的一个例子

例 使用NSRecursiveLock

@interface ThreadSafeClass ()
{
    NSRecursiveLock *lock;
}
@end

- (instancetype)init {
    if (self = [super init]) {
        self->lock = [NSRecursiveLock new];
    }
    return self;
}
- (void)safeMehod1 {
    [self->lock lock];
    [self safeMehod2];
    [self->lock unlock];
}

- (void)safeMehod2 {
    [self->lock lock];
    /// 线程安全
    [self->lock unlock];
}
  • NSRecursiveLock对象。
  • safeMehod1方法获取锁。
  • 它调用了safeMehod2方法。
  • safeMehod2从已经获取的锁再次获取了锁。
  • safeMehod2释放了锁。
  • safeMehod1释放了锁
  • safeMehod1释放了锁。因为每个锁定操作都有一个相应的解锁操作与之匹配,所以锁再次被释放,并可以被其他线程获取。

相关文章

网友评论

    本文标题:NSLock, NSRecursiveLock

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