上一篇介绍了常用的多线程技术,目前开发中比较常用的是GCD,其它的熟悉即可。多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用率来提高系统的整体性能,但是会出现多个线程对同一资源的抢夺,可能会引起线程的安全问题。 这时候可能需要创建一个单例对象来解决资源争夺问题,比较典型的是“卖票”问题

1、单例对象的创建

  1> 定义一个全局的静态变量,记录第一次被实例化出来的对象,并在后续使用

  2> 重写allocWithZone方法,并利用dispatch_once_t实例化线程安全的对象

  3> 定义以shared或者default开头的类方法,供外界创建

 #import <Foundation/Foundation.h>

 @interface Tickets : NSObject

 // 要使用互斥锁,需要两个条件
// 1. 将要强夺的资源设置为原子属性,只有设置了原子属性,才能够保证线程安全
// 2. 在读写原子属性的代码处,使用互斥锁@synchronized
@property (atomic, assign) NSInteger num; // 票数 // 提供给外界的类方法,一般以shared或者default开头
+ (instancetype)sharedTickets; @end
 #import "Tickets.h"

 static Tickets *_instance;

 @implementation Tickets

 + (id)allocWithZone:(struct _NSZone *)zone
{
// dispatch_once_t是gcd提供的一种多线程实例化对象的方法
// 使用此方法,可以保证在多线程情况下,始终仅能实例化出来一个对象
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
}); return _instance;
} + (instancetype)sharedTickets
{
if (!_instance) {
_instance = [[Tickets alloc] init];
} return _instance;
} @end

2、 创建多个异步线程,并执行卖票方法

 - (void)viewDidLoad
{
[super viewDidLoad]; [Tickets sharedTickets].num = ; // 创建多个线程异步售票
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); dispatch_async(queue, ^{
[self sellTicketBy:@"p-1"];
}); dispatch_async(queue, ^{
[self sellTicketBy:@"p-2"];
}); }

3、 在访问原子属性时,加互斥锁

 - (void)sellTicketBy:(NSString *)name
{
while (YES) { // 在访问原子属性的地方加互斥锁
@synchronized(self){
if ([Tickets sharedTickets].num > ) {
[Tickets sharedTickets].num--;
NSLog(@"剩余票数-%@-%d", name, [Tickets sharedTickets].num);
}else{
NSLog(@"票卖完了");
break;
}
} // 让线程休眠,用于模拟售票员的效率不同
if ([name isEqualToString:@"p-1"]) {
[NSThread sleepForTimeInterval:1.0f];
}else{
[NSThread sleepForTimeInterval:0.5f];
}
}
}

至此一个简单的模拟售票,处理多线程资源争夺的demo就完成了。

但是还有几点需要注意的:

1、互斥锁是非常消耗性能的,应该使加锁的内容越少越好

2、单例对象里应该重写copy、retain(非ARC)等方法,以防止团队里的其他人通过另类的方法创建单例对象。

ios开发之多线程资源争夺的更多相关文章

  1. iOS开发之多线程技术

    本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...

  2. iOS开发-多线程开发之线程安全篇

    前言:一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象.同一个变量.同一个文件和同一个方法等.因此当多个线程访问同一块资源时,很容易会发生数据错误及数据不安 ...

  3. iOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

    简介 在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间 ...

  4. ios开发之多线程---GCD

    一:基本概念 1:进程:正在运行的程序为进程. 2:线程:每个进程要想执行任务必须得有线程,进程中任务的执行都是在线程中. 3:线程的串行:一条线程里任务的执行都是串行的,假如有一个进程开辟了一条线程 ...

  5. iOS开发之多线程(NSThread、NSOperation、GCD)

    整理一些多线程相关的知识. 并行 & 并发 1.并行:并行是相对于多核而言的,几个任务同时执行.2.并发:并发是相对于单核而言的,几个任务之间快速切换运行,看起来像是"同时" ...

  6. iOS开发中多线程基础

    耗时操作演练 代码演练 编写耗时方法 - (void)longOperation { for (int i = 0; i < 10000; ++i) { NSLog(@"%@ %d&q ...

  7. iOS开发之多线程技术(NSThread、OperationQueue、GCD)

    在前面的博客中如果用到了异步请求的话,也是用到的第三方的东西,没有正儿八经的用过iOS中多线程的东西.其实多线程的东西还是蛮重要的,如果对于之前学过操作系统的小伙伴来说,理解多线程的东西还是比较容易的 ...

  8. iOS开发之多线程技术——GCD篇

    本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...

  9. iOS开发之多线程技术—GCD篇

    本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...

随机推荐

  1. [老老实实学WCF] 第十篇 消息通信模式(下) 双工

    老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...

  2. jQuery鼠标事件

    鼠标事件是在用户移动鼠标光标或者使用任意鼠标键点击时触发的.   (1):click事件:click事件于用户在元素敲击鼠标左键,并在相同元素上松开左键时触发.        $('p').click ...

  3. Optimistic Offline Lock乐观离线锁

    通过冲突检测和(发生冲突时的)事务回滚,来防止并发业务事务中的冲突. 通常一个业务事务的执行,会跨越一系列的系统事务. 一旦超出了单个系统事务的范围,就不能仅依靠DB管理程序来保证数据一致性. 乐观离 ...

  4. js获取url及url参数的方法

    <script language="JavaScript" type="text/javascript"> function GetUrlParms ...

  5. android ListView的怪异现象

    我们已经知道,当条目没显示一次,那个类重写的最后一个函数就执行一次,但是现在,发生了怪异现象!当窗体的属性设置为包裹的时候,会重复显示多次,所以,高度,宽度都要设置为充满类型才可以

  6. 利用word2vec对关键词进行聚类

    1.收集预料 自己写个爬虫去收集网页上的数据. 使用别人提供好的数据http://www.sogou.com/labs/dl/ca.html 2.对预料进行去噪和分词 我们需要content其中的值, ...

  7. ubuntu下安装 Source insight

    习惯了在source insight下编辑阅读源码,在linux下用vi总是用不好 ,还是在ubuntu上用回熟悉的source insight. 在ubuntu中,安装windows程序用wine, ...

  8. Java内存溢出详解

    转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap ...

  9. mysql 的数据类型

    mysql 的数据类型(描述的是字段)三大类:一.整型:1.tinyint(M),其中M是显示宽度,需要配合zerofill,就是前面0填充,存储单位为1个字节(8位),无符文是最大能存储范围0000 ...

  10. 【笔记】W3C CSS关键属性

    white-space属性: white-space 属性设置如何处理元素内的空白. 可能的值 值 描述 normal 默认值,合并所有空格,换行符会被浏览器忽略 pre 空白会被浏览器保留.其行为方 ...