设为首页 加入收藏

TOP

iOS 多线程 NSOperation、NSOperationQueue(六)
2019-08-31 00:20:48 】 浏览:108
Tags:iOS 线程 NSOperation NSOperationQueue
k 对象可以通过进入锁时调用 lock 方法,解锁时调用 unlock 方法来保证线程安全。

考虑线程安全的代码:

/** * 线程安全:使用 NSLock 加锁 * 初始化火车票数量、卖票窗口(线程安全)、并开始卖票 */ - (void)initTicketStatusSave { NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印当前线程 self.ticketSurplusCount = 50; self.lock = [[NSLock alloc] init]; // 初始化 NSLock 对象 // 1.创建 queue1,queue1 代表北京火车票售卖窗口 NSOperationQueue *queue1 = [[NSOperationQueue alloc] init]; queue1.maxConcurrentOperationCount = 1; // 2.创建 queue2,queue2 代表上海火车票售卖窗口 NSOperationQueue *queue2 = [[NSOperationQueue alloc] init]; queue2.maxConcurrentOperationCount = 1; // 3.创建卖票操作 op1 NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ [self saleTicketSafe]; }]; // 4.创建卖票操作 op2 NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ [self saleTicketSafe]; }]; // 5.添加操作,开始卖票 [queue1 addOperation:op1]; [queue2 addOperation:op2]; } /** * 售卖火车票(线程安全) */ - (void)saleTicketSafe { while (1) { // 加锁 [self.lock lock]; if (self.ticketSurplusCount > 0) { //如果还有票,继续售卖 self.ticketSurplusCount--; NSLog(@"%@", [NSString stringWithFormat:@"剩余票数:%d 窗口:%@", self.ticketSurplusCount, [NSThread currentThread]]); [NSThread sleepForTimeInterval:0.2]; } // 解锁 [self.lock unlock]; if (self.ticketSurplusCount <= 0) { NSLog(@"所有火车票均已售完"); break; } } } 

输出结果:


 
 

省略一部分结果图。。。


 
 
  • 可以看出:在考虑了线程安全,使用 NSLock 加锁、解锁机制的情况下,得到的票数是正确的,没有出现混乱的情况。我们也就解决了多个线程同步的问题。

10. NSOperation、NSOperationQueue 常用属性和方法归纳

10.1 NSOperation 常用属性和方法

  1. 取消操作方法
    • - (void)cancel;可取消操作,实质是标记 isCancelled 状态。
  2. 判断操作状态方法
    • - (BOOL)isFinished;判断操作是否已经结束。
    • - (BOOL)isCancelled;判断操作是否已经标记为取消。
    • - (BOOL)isExecuting;判断操作是否正在在运行。
    • - (BOOL)isReady;判断操作是否处于准备就绪状态,这个值和操作的依赖关系相关。
  3. 操作同步
    • - (void)waitUntilFinished;阻塞当前线程,直到该操作结束。可用于线程执行顺序的同步。
    • - (void)setCompletionBlock:(void (^)(void))block;completionBlock会在当前操作执行完毕时执行 completionBlock。
    • - (void)addDependency:(NSOperation *)op;添加依赖,使当前操作依赖于操作 op 的完成。
    • - (void)removeDependency:(NSOperation *)op;移除依赖,取消当前操作对操作 op 的依赖。
    • @property (readonly, copy) NSArray<NSOperation *> *dependencies;在当前操作开始执行之前完成执行的所有操作对象数组。

10.2 NSOperationQueue 常用属性和方法

  1. 取消/暂停/恢复操作
    • - (void)cancelAllOperations;可以取消队列的所有操作。
    • - (BOOL)isSuspended;判断队列是否处于暂停状态。 YES 为暂停状态,NO 为恢复状态。
    • - (void)setSuspended:(BOOL)b;可设置操作的暂停和恢复,YES 代表暂停队列,NO 代表恢复队列。
  2. 操作同步
    • - (void)waitUntilAllOperationsAreFinished;阻塞当前线程,直到队列中的操作全部执行完毕。
  3. 添加/获取操作`
    • - (void)addOperationWithBlock:(void (^)(void))block;向队列中添加一个 NSBlockOperation 类型操作对象。
    • - (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;向队列中添加操作数组,wait 标志是否阻塞当前线程直到所有操作结束
    • - (NSArray *)operations;当前在队列中的操作数组(某个操作执行结束后会自动从这个数组清除)。
    • - (NSUInteger)operationCount;当前队列中的操作数。
  4. 获取队列
    • + (id)currentQueue;获取当前队列,如果当前线程不是在 NSOperationQueue 上运行则返回 nil。
    • + (id)mainQueue;获取主队列。

注意:

  1. 这里的暂停和取消(包括操作的取消和队列的取消)并不代表可以将当前的操作立即取消,而是当当前的操作执行完毕之后不再执行新的操作。
  2. 暂停和取消的区别就在于:暂停操作之后还可以恢复操作,继续向下执行;而取消操作之后,所有的操作就清空了,无法再接着执行剩下的操作。

 



作者:行走的少年郎
链接:https://www.jianshu.com/p/4b1d77054b35
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
首页 上一页 3 4 5 6 下一页 尾页 6/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[iOS]异常捕捉 下一篇ipa的plist文件查看

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目