引言:我们开发中可能会用到多线程,但是同时也会引发多线程安全问题,例如卖票问题,这个时候就引入了一些线程锁来保证线程安全,我们常用的线程锁有哪些呢?
1.OSSpinLock,是一种自旋锁,发现代码加锁后会进入忙等状态,直到解锁,效率低,目前不推荐使用,可能会造成优先级反转问题
static OSSpinLock lock = OS_SPINLOCK_INIT;初始化锁
OSSpinLockLock(&lock);//加锁
//代码段
OSSpinLockUnlock(&lock);//解锁
2.os_unfair_lock,是OSSpinLock的替代品,在IOS10.0以后才可以使用
static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;//初始化锁
os_unfair_lock_lock(&lock);//加锁
//代码段
os_unfair_lock_unlock(&lock);//解锁
3.pthread_metex,是一种跨平台的互斥锁,不会忙等
pthread_mutexattr_t attr;//设置属性
pthread_mutexattr_init(&attr);//初始化属性
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);//设置锁的类型
pthread_mutex_init(&_mutex, &attr);//初始化锁
pthread_mutexattr_destroy(&attr);//销毁锁
pthread_mutex_lock(&_mutex);//加锁
//代码段
pthread_mutex_unlock(&_mutex);解锁
4.NSLock,基于pthread_metex普通锁的封装,更加面向对象
self.lock = [[NSLock alloc] init];//初始化
[_lock lock];//加锁
//代码段
[_lock unlock];//解锁
5.NSRecursiveLock,基于pthread_metex递归锁的封装,递归代码使用
self.lock = [[NSRecursiveLock alloc] init];//初始化
[self.lock lock];//加锁
//代码段
[self.lock unlock];解锁
6.NSCondition,基于pthread_metex条件锁的封装
self.condition = [[NSCondition alloc] init];//初始化
[self.condition lock];//加锁
[self.condition wait];//等待
[self.condition unlock];//解锁
[self.condition signal];//发送信号
[self.condition broadcast];//发送广播
执行wait代码后会阻塞当前线程,不执行后面的代码,直到发送信号或广播后,才会告诉线程继续执行后面代码
7.NSConditionLock,对NSCondition的进一步封装,增加了一些条件
8.dispatch_semaphore_t,信号量,推荐使用,各大第三方都在使用
self.semaphore = dispatch_semaphore_create(1);//初始化并设置最大并发数为3
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);//如果信号量的值>0,就让信号量的值-1并执行接下来的代码,如果信号量的值<=0,则休眠等待,直到信号量的值>0,就让信号量的值-1,并往下执行
//代码段
dispatch_semaphore_signal(self.semaphore);//让信号量的值+1
9.@synchronized,对mutex的递归锁的封装,新能差,不推荐使用
@synchronized(self) {
//执行代码
}
10.pthread_rwlock_t,是一种多读单写的锁,主要用在I/O操作,I/O操作如果使用普通的锁,是单读单写,大大降低了效率,pthread_rwlock_t可以多读单写,在保证线程安全的前提下大大提升读取的效率,我们使用GCD的dispatch_barrier_async也同样可以实现
@property (nonatomic, assign) pthread_rwlock_t lock;
pthread_rwlock_init(&_lock, NULL);//初始化
pthread_rwlock_rdlock(&_lock);//读取加锁
//读取代码
pthread_rwlock_unlock(&_lock);//解锁
pthread_rwlock_wrlock(&_lock);//写入加锁
//写入代码
pthread_rwlock_unlock(&_lock);//解锁 pthread_rwlock_destroy(&_lock);//销毁