引文:
-
GCD
-
NSOperation
-
NSThread
-
多线程与锁
注意: 在主线程中执行同步任务将发生死锁
死锁原因
系统在主队列开启主线程执行任务,用户手动添加一个同步任务到当当前线程中,由于同步任务不开辟额外的线程去处理,所以就在当前线程中去执行任务,由于当前线程是主线程,所有就造成任务的相互等待过程从而产生死锁.
同步串行
思考: 输出什么?
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:self afterDelay:2];
NSLog(@"2"); });
}
- (void)test{
NSLog(@"test");
}
输出: 1 2
不会输出test.
因为
performSelector
方法要添加到对应线程的runloop
之后才会生效,由于异步任务是在dispatch_get_global_queue
并发队列中的, 默认不开启runloop
,所有不会执行.如果是添加到主队列中,就会执行了.
Dispathc_barrier_async() (栅栏模式)
可以实现多读单写.
Dispatch_group_async() (组别模式)
可以实现多任务执行完毕后统一处理后续业务逻辑
NSOperation
需要和NSOperationQueue
配合使用来实现多线程方案
特点:
-
添加任务依赖
-
认为执行状态控制
isReady --> 准备
isExecuting --> 执行
isFinished --> 完成
isCancelled --> 取消
如果只重写main方法,底层控制变更任务执行状态,以及任务的退出
如果重写了start方法, 自行控制任务的执行状态 设置最大并发量
锁
@synchronized
一般创建单例对象使用
atomic
修饰属性的关键字
对被修饰对象进行原子操作(不负责使用)
@property (atomic) NSMutableArray *arr;
self.arr = [NSMutableArray array]; //✔️
[self.arr addObject:@"1"]; // ❎ 不负责使用
自旋锁(OSSpinLock)
循环等待询问,不释放当前资源.
用于轻量级数据访问
NSLock
- (void)test{
NSLock *lock = [[NSLock alloc] init];
[lock lock];
[self test2];
[lock unlock];
}
- (void)test2{
NSLock *lock = [[NSLock alloc] init];
[lock lock];
[self test3];
[lock unlock];
}
会造成死锁 ,解决方案是使用递归锁
递归锁 (NSRecureiveLock)
可以无限重入
- (void)test{
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
[lock lock];
[self test2];
[lock unlock];
}
- (void)test2{
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
[lock lock];
// 业务逻辑
[lock unlock];
}