线程安全,线程同步技术(线程安全解决方案)
多线程带来的安全隐患 :
1. 一块资源可能被多个线程共享,也就是多个线程可能同时访问一块资源
2.比如多个线程访问一个对象,统一变量,同一文件。
3.当多个线程访问一块资源时,很容易引发数据错乱和数据安全问题
解决方案:线程同步技术,常用的线程同步技术 加锁 (多条线程 访问同一资源 才需要加锁 )
4.iOS线程同步方案如下:注意点 访问同一块资源任务,保证所有线程使用同一把锁
4.1
Osspinlock 自旋锁,忙等的锁,一直暂用cpu资源,目前不安全不建议使用,有优先级反转问题
API: OSSpinLock moneyLock = OS_SPINLOCK_INIT; OSSpinLockLock(&_moneyLock);OSSpinLockUnlock(&_moneyLock);(#import <libkern/OSAtomic.h>)
4.2
os_unfair_lock iOS10针对osspinlock优先级反转问题,提供的新解决方案
API: os_unfair_lock moneyLock = OS_UNFAIR_LOCK_INIT;os_unfair_lock_lock(&_ticketLock);os_unfair_lock_unlock(&_ticketLock);
#import <os/lock.h>
4.3
phread_mutex 跨平台C语言锁
API: #import <pthread.h>
pthread_mutex_t ticketMutex
- (void)__initMutex:(pthread_mutex_t *)mutex {
// 初始化属性
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(&_ticketMutex);
pthread_mutex_unlock(&_ticketMutex);
pthread_mutex_destroy(&_mutex);
4.4
dispatch_semaphore 信号量,可控制线程的最大并发
API: dispatch_semaphore_t semaphore;
self.semaphore = dispatch_semaphore_create(5);
dispatch_semaphore_wait(self.moneySemaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(self.moneySemaphore);
4.5
dipatch_queue(dispatch_quue_serial) 串行队列
API: self.ticketQueue = dispatch_queue_create("ticketQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(self.moneyQueue, ^{ });
4.6
NSLock 对phread_mutex 默认模式的封装
API: ticketLock = [[NSLock alloc] init]; [self.ticketLock lock]; [self.ticketLock unlock];
4.7 NSRecursivelock 对phread_mutex 递归模式的封装
4.8
NSCondition 对phread_mutex 条件模式的封装
API: self.condition = [[NSCondition alloc] init]; [self.condition lock]; [self.condition wait]; [self.data removeLastObject];[self.condition unlock]; [self.condition signal];
4.9
NSConditionLock 对nscondition的封装,可传入具体条件,用于多个线程依赖关系
API:
self.conditionLock = [[NSConditionLock alloc] initWithCondition:1];
[self.conditionLock lockWhenCondition:2];
[self.conditionLock unlockWithCondition:2];
4.10
@syncchrinized 使用最简单,锁住一个对象,性能比较差
API : @synchronized([self class]) {}
5.性能由高到低一次是:os_unfair_lock osspinlock dispatch_semaphore dipatch_queue phread_mutex nslock nsrecursivelock nscondition nsconditionLock @syncchrinized
6.自旋锁与互斥锁比较:在cpu够花销的情况下自旋锁性能更优,因为少了休眠跟唤起休眠的步骤,对cpu性能要求高的代码使用,调用频繁的代码建议使用自旋锁
7. atomic 原子属性,体层原理就是 seter geter 方法里加锁了。只能保证seter geter方法线程安全
浙公网安备 33010602011771号