iOS中的锁

OSSpinLock自旋锁

(虽然已经被证明不安全优先级翻转),性能最高的锁。原理很简单,就是一直做而忙等。它的缺点是当等待时会消耗大量CPU资源,所以它不适用于较长时间的任务对于内存缓存的存取来说,它非常合适。轻量级,比如sideTable表的访问

 

dispatch_semaphore(同步)

dispatch_semaphore是GCD用来同步的一种方式。允许通过等待/信号的信号事件控制并发执行的最大线程数,当最大线程数降级为1的时候则可当作同步锁使用,相对于OSSpinLock来说,它的优势在于等待时不会消耗CPU资源。对磁盘缓存来说,它比较合适,YYCache中大量用到

 

NSLock(同步)(可以对一段代码加锁)

典型的面向对象的锁,即同步锁类。所有锁(包括NSLock)遵循Objective-C的NSLocking协议接口,支持tryLock和lockBeforeDate:。底层通过pthread_mutex实现。

NSLock * lock = [[NSLock alloc] init];

if([lock tryLock]){//尝试加锁,如果失败返回NO,不会阻塞该线程
    [lock unlock];
}
if([lock lockBeforeDate:date]){//在Date之前尝试加锁,如果不能加锁,则返回NO
    [lock unlock];
}

使用注意:第一:加锁和解锁必须再一个线程,第二:不能连续加锁两次
 

NSRecursiveLock递归锁
NSRecursiveLock和NSLock一样是面向对象的锁,但是支持递归,不支持tryLock。这个锁可以被同一线程多次请求,而不会引起死锁。这主要是用在循环或递归操作中。

NSRecursiveLock * theLock = [[NSRecursiveLock alloc] init];

void RecursiveFunction(int value){
    [theLock lock];
    if(value!= 0){ -
        value;
        RecursiveFunction(值);
    }
    [theLock unlock];
}

RecursiveFunction(5);

 

NSConditionLock条件锁
NSConditionLock可以使用特定值来加锁和解锁。相比NSCondition更为直接和实用。

id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA];
while(true){
    [condLock lock];
    / *将数据添加到队列中。* /
    [condLock unlockWithCondition:HAS_DATA];
}
 

@Synchronized(互斥锁)(只能对一个对象加锁)

优点:能有效防止因多线程抢夺资源造成的数据安全问题

缺点:需要消耗大量的CPU资源

互斥锁的使用前提:多条线程抢夺同一块资源的时候使用。

 

pthread_mutex
POSIX标准的unix多线程库(pthread)中使用的互听量,支持while循环。

pthread_mutex_t lock
pthread_mutex_init(&lock,NULL);
的pthread_mutex_lock(锁);加锁
pthread_mutex_tylock(锁); / pthread_mutex_trylock(&lock)== 0
pthread_mutex_unlock(&lock);
pthread_mutex_destroy(锁);
 

结论常规
和while循环加锁使用pthread_mutex。
队列(dispatch_get_global_queue)并发线程数控制,使用dispatch_semaphore。
递归调用时使用NSRecursiveLock(项目中不建议使用此方案,风险高)。
性能要求极度苛刻时,考虑使用OSSpinLock,不过需要确保加锁片段的耗时足够小。
不建议使用NSLock,pthread_mutex(递归),NSCondition,NSConditionLock和@synchronized。
 

 

你可能感兴趣的:(iOS学习)