IOS多线程开发之线程安全

224 阅读2分钟

引言:我们开发中可能会用到多线程,但是同时也会引发多线程安全问题,例如卖票问题,这个时候就引入了一些线程锁来保证线程安全,我们常用的线程锁有哪些呢?

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);//销毁