性能从高到低排序:
os_unfair_lock
示例代码:
#import <os/lock.h>
@property (nonatomic, assign) os_unfair_lock lock;
// 初始化
_lock = OS_UNFAIR_LOCK_INIT;
// 加锁
os_unfair_lock_lock(&_lock);
// 解锁
os_unfair_lock_unlock(&_lock);
// 尝试加锁解锁
if (os_unfair_lock_trylock(&_lock)) {
os_unfair_lock_unlock(&_lock);
}
OSSpinLock
自旋锁,等待锁的线程会处于忙等(busy-wait)状态,一直占用CPU资源
示例代码:
#import <libkern/OSAtomic.h>
@property (nonatomic, assign) OSSpinLock lock;
// 初始化
_lock = OS_SPINLOCK_INIT;
// 加锁
OSSpinLockLock(&_lock);
// 解锁
OSSpinLockUnlock(&_lock);
// 尝试加锁解锁
if (OSSpinLockTry(&_lock)) {
OSSpinLockUnlock(&_lock);
}
dispatch_semaphore
信号锁
semaphore是信号量
,信号量的初始值,可以用来控制线程并发访问的最大数量
示例代码:
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
// 设置信号量最多的数量,也就是最多可以运行的线程的数量
self.semaphore = dispatch_semaphore_create(5);
// 开启多线程
for (int i = 0; i < 20; ++i) {
[[[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil] start];
}
// 如果信号量>0,信号量-1,继续执行
// 否则,当前线程进入休眠,并等待信号量>0
// 执行结束后,信号量+1
- (void)task {
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(self.semaphore);
}
pthread_mutex
互斥锁,等待锁的线程会处于休眠状态
示例代码:
#import <pthread.h>
@property (assign, nonatomic) pthread_mutex_t mutex;
// 1. 初始化锁的属性
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
// PTHREAD_MUTEX_NORMAL
// PTHREAD_MUTEX_ERRORCHECK
// PTHREAD_MUTEX_RECURSIVE
// PTHREAD_MUTEX_DEFAULT
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_DEFAULT);
// 2. 初始化锁
pthread_mutex_init(&_mutex, &mutexattr);
// 或者锁的属性传NULL,默认为PTHREAD_MUTEX_DEFAULT
pthread_mutex_init(&_mutex, NULL);
// 3. 销毁锁的属性
pthread_mutexattr_destroy(&mutexattr);
// 4. 加锁
pthread_mutex_lock(&_mutex);
pthread_mutex_trylock(&_mutex);
// 5. 解锁
pthread_mutex_unlock(&_mutex);
// 6. 销毁锁
pthread_mutex_destroy(&_mutex);
递归锁:允许同一个线程重复加锁
示例代码:
- (void)mutex_1 {
// 加锁
pthread_mutex_lock(&_mutex);
[self mutex_2];
// 解锁
pthread_mutex_unlock(&_mutex);
}
- (void)mutex_2 {
// 加锁
pthread_mutex_lock(&_mutex);
// 解锁
pthread_mutex_unlock(&_mutex);
}
运行后,会造成死锁
解决方法:设置递归锁
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
条件锁:
假设有两条线程的两个任务,第一个任务需要等待第二个任务执行结束才能执行,这时需要条件锁
示例代码:
#import <pthread.h>
@property (assign, nonatomic) pthread_cond_t cond;
// 1. 初始化条件锁
pthread_cond_init(cond, NULL);
// 2. 执行任务
- (void)mission_1 {
// 加锁
pthread_mutex_lock(&_mutex);
if (条件判断) {
// 等待
pthread_cond_wait(&_cond, &_mutex);
}
// 解锁
pthread_mutex_unlock(&_mutex);
}
- (void)mission_2 {
// 加锁
pthread_mutex_lock(&_mutex);
// 激活等待
pthread_cond_signal(&_cond);
// 或者
// 激活所有等待
pthread_cond_broadcast(&_cond);
// 解锁
pthread_mutex_unlock(&_mutex);
}
// 3. 释放资源
pthread_cond_destroy(&_cond);
dispatch_queue(DISPATCH_QUEUE_SERIAL)
原理:
串行队列的特点是,其中的任务只能一个一个执行,不能同时取出多个任务
将需要执行的任务放入串行队列中,这样多个线程执行任务时,必须在前一个任务执行完毕后,才能执行后一个任务
示例代码:
@property (nonatomic, strong) dispatch_queue_t queue;
self.queue = dispatch_queue_create("queue_label", DISPATCH_QUEUE_SERIAL);
// 开启多线程
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
[self task];
});
dispatch_async(queue, ^{
[self task];
});
dispatch_async(queue, ^{
[self task];
});
// 线程同步
- (void)task {
dispatch_sync(self.queue, ^{
});
}
NSLock
基于pthread_mutex的PTHREAD_MUTEX_NORMAL类型的封装
示例代码:
@property (nonatomic, strong) NSLock *lock;
self.lock = [[NSLock alloc] init];
// 加锁
[self.lock lock];
// 解锁
[self.lock unlock];
NSCondition
对pthread_mutex和pthread_cond的封装
示例代码:
@property (nonatomic, strong) NSCondition *condition;
// 1. 初始化
self.condition = [[NSCondition alloc] init];
// 2. 执行任务
- (void)mission_1 {
// 加锁
[self.condition lock];
if (等待条件) {
// 等待
[self.condition wait];
}
// 解锁
[self.condition unlock];
}
- (void)mission_2 {
// 加锁
[self.condition lock];
// 激活
[self.condition signal];
// 或者
// 激活所有
[self.condition broadcast];
// 解锁
[self.condition unlock];
}
pthread_mutex(recursive)
NSRecursiveLock
基于pthread_mutex的PTHREAD_MUTEX_RECURSIVE(递归锁)类型的封装
使用方法同NSLock
NSConditionLock
对NSCondition的进一步封装,可以设置具体的条件值
示例代码:
@property (nonatomic, strong) NSConditionLock *lock;
// 1. 初始化
self.lock = [[NSConditionLock alloc] initWithCondition:1];
// 2. 加锁/解锁
- (void)task_1 {
// 加锁
[self.lock lockWhenCondition:1];
// 解锁
[self.lock unlockWithCondition:2];
}
- (void)task_2 {
// 加锁
[self.lock lockWhenCondition:2];
// 解锁
[self.lock unlockWithCondition:3];
}
- (void)task_3 {
// 加锁
[self.lock lockWhenCondition:3];
// 解锁
[self.lock unlock];
}
这段代码的执行流程:
- 初始化锁并设置加锁条件为1
- 三个任务中,仅task_1的加锁条件为1,所以task_1执行并加锁,其他任务因为加锁条件不为1而无法执行(等待)并加锁
- task_1执行结束,解锁并设置加锁条件为2
- 剩下的两个任务中,仅task_2的加锁条件为2,所以task_2执行并加锁,而task_3继续等待
- task_2执行结束,解锁并设置加锁条件为3
- 因为task_3的加锁条件为3,所以task_3等待结束并加锁
- task_3执行结束,解锁
@synchronized
对pthread_mutex的封装
示例代码:
@synchronized (索引对象) {
}