码迷,mamicode.com
首页 > 编程语言 > 详细

多线程01

时间:2015-09-02 01:52:28      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

 
/*------------------------------ GCD使用 1.队列和任务------------------------------------------*/
重点:1. “串行队列”? “并发队列”? 2.block?
1.GCD(Crand Central  Dispatch) — “牛逼的中枢调度器”!
 
//C语言框架/ 自动管理线程的生命周期(创建/释放)
 
推出GCD 的目的:取代NSThread!
为”多核”的”并发” 运算提出的解决方案!
 
优点:
<1> GCD 能够自动利用更多的CPU的核数(双核/四核)!
<2> GCD 会自动管理线程的生命周期.
 
程序员只需要告诉GCD 想要执行的任务(代码)!
 
2.GCD中的两个核心概念:
 
“任务”:
          想要做的事情/执行什么操作
          GCD 中的任务定义在block中.
          void(^myblock)( ) = ^{
// 想要做的事情/任务
}
“队列”:
          用来”存放”任务!
 
队列 != 线程!  队列不是线程
 
队列中存放的任务最后都要由线程来执行!
 
队列的原则: 先进先出,后进后出(FIFO/ first In First Out)
 
队列的类型: 
queue 队列 
Serial  串 
Dispatch
<1> 串行 队列:(Serial  Dispatch Queue)
// 创建一个串行队列
dispatch_queue_t serialQueue = dispatch_queue_create(“serial”,DISPATCH_QUEUE_SERIAL);
 
<2> 并发队列 :(Concurrent  Dispatch  Queue)
concurrent   同时
 
//创建一个并发队列
dispatch_queue_t concurrentQueue = dispatch_queue_create(“concurrent”,DISPATCH_QUEUE_CONCURRENT);
 
注意两个非常常用的特殊队列;
<1> 主队类: // UI操作放在主队列中执行!
        跟主线程相关联的队列!
        主队列是 GCD 自带的一种特殊的串行队列!
        主队列中的任务都会在主线程执行!
 
//获取主队类
dispatch_queue_t mainQueue = dispatch_get_main_queue();
 
<2> 全局并发队列 :// 一般情况下,并发任务都可以放在全局并发队列中!
//获取主队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(0,0);
 
 
/*-----------------------------------  GCD使用 2.执行任务 -------------------------------------*/
 
重点:1 .同步函数 异步函数 2.容易混淆的四个概念: 串行  并发,同步,异步之间的区别?
 
问题:串行队列中的任务必定按照顺序吗?并发队列中的任务必定同时执行吗?
 
GCD中有两个用来执行任务的函数;
 
同步 执行任务:
dispatch_sync(^(void)block dispatch_dispatch_queue_t queue,)
 
异步 执行任务;
dispatch_async(dispatch_queue_t queue,^(void)block)
//dispatch_queue_t queue 队列
//^(void)block: 任务
 
同步和异步的区别:
同步:只能在当前线程任务中执行任务,不具备开启新线程的能力
异步: 可以在新的线程中执行任务,具备开启新线程的能力
 
GCD 使用有两个步骤;
<1> 将任务添加到队列中;
<2> 选择同步还是异步的方式执行任务.
 
注意:四个容易混淆的术语
串行   并发 (  同步    异步 函数)
 
 
/*-------------------------------  GCD使用 3.各种队列的执行效果 ---------------------------------*/
 
重点: 1.掌握连个常用的组合!
常见的组合(掌握)
async 异步执行函数
1>dispatch_async + 全局并发队列 (可以开启多条线程)  
2>dispatch_async + 自己创建的串行队列 (开启一条线程)
 
只有异步执行并发队列,才可以开启多条线程
 
注意:
在主线程中同步执行主队列任务,会造成 主线程和主队列 相互等待,卡住线程!
 
 
/*-------------------------------  GCD使用 4.线程间通信 ---------------------------------------*/
 
重点:1.从子线程回到主线程(经典用法) ! 2.两个注意点.
1.经典用法(子线程下载(耗时操作),主线程刷新UI):
dispatch_async(dispatch_get_global_queue)(0,0),^{
 
//执行 耗时的异步操作
dispatch_async(dispatch_get_main_queue(),^{
     //回到主线程,执行UI刷新操作
 
});
 
});
 
2.注意: custom  习惯
<1> 需要设置按钮的image,建议先把按钮类型改为custom,才能保证设置成功
<2> 属性名不能以new开头
 
/*-------------------------------  GCD使用 5.延时执行  -----------------------------------------*/
 
重点: 1. iOS常见的两种延时执行方式
 
iOS中的延时执行方式;
//定制好延时任务后,不会阻塞当前线程.
 
<1> 调用NSObject 方法:
[self  performSelector:@selector(run) withObject:nil afterDelay:2.0];
//2秒后再调用self的run方法
 
<2> GCD 函数实现延时执行:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)
(2.0 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
 
//2秒后执行这里的代码…在哪个线程执行,跟队列类型有关
});
 
注意:
不要使用sleep,会阻塞当前线程,
 
 
/*-------------------------------  GCD使用 6.队列组  ------------------------------------------*/
 
重点:1.了解队列组的使用方法
项目需求:
首先:分别异步执行两个耗时操作;
其次:等两次耗时操纵都执行完毕后,在回到主线程执行操作.
 
使用队列组(dispatch_group_t)快速,高效的实现上述需求.
group   群组
dispatch_group_t group = dispatch_group_create();//队列组
 
 
dispatch_group_t  group  = dispatch_get_global_queue(0,0);   //全局并发队列
 
dispatch_group_async(group,queue,^{
 
//longTime2  
});  //异步执行操作
 
 
dispatch_group_notify(group,dispatch_get_main_queue(),
^{
     //在主线程刷新新数据
reload 刷新
//reload   Data
 
});
 
/*-------------------------------  GCD使用 7.一次性代码 ---------------------------------------*/
重点:1.掌握一次性代码的实现
一次性代码;
static 静止的不变的
Token 标志
static dispatch_once_t onceToken;
dispatch_once(&onceToken),^{
//只执行一次的代码(这里面默认是线程安全的)
});
 
/*--------------------------------------  补充: 单例设计模式 -----------------------------------*/
 
重点:1.掌握单例!
1.单例简介:
 
作用;
     保证程序在运行过程中,一个类只有一个实例对象,这个实例对象容易被外界访问!
     控制器实例对象个数(只有一个) ,节约系统资源.
 
使用场合;
     在整个应用程序中,共享一份资源(这份资源只需要创建初始化一次).
举例;
打印机/视图窗口/一些网络工具类等等
 
//懒汉式:用到的时候再加载
//饿汉式:只要程序运行就加载: //不需要掌握.也不要这么写!
//掌握懒汉式
 
2.单例实现:(两种方式:互斥锁(@synchronized)(self))和一次性代码(dispatch_once));
 
2.1  互斥锁 @synchronized(self);
 
<1> 在.m文件中保留一个全局的 static 的实例
static  id _instance;
 
zone 分区  with  和...一起 alloc  分配存储空间
<2> 重写若干方法(allocWithZone:和 copyWithZone:) 并提供一个类方法让外界访问唯一的实例.
 
//(1) allocWithZoneL:方法,在这里创建唯一的实例(注意线程安全). //alloc 内部都会调用这个方法
 
+(instancetype) allocWIthZone:(struct  _NSZone *)zone{
if(_instance == nil){ //防止频繁加锁
@synchronized (self){
if(_instance == nil) //防止创建多次
{
     _instance = [super  allocWithZone:zone];
}
}
     
}
return _instance;
 
}
 
 
//(2) 重写copyWithZone:方法
+(id)copyWithZone:(struct _NSZone *)zone
{
     return  _instance;
}
 
//(3) 提供一个类方法让外界访问唯一的实例
+(instancetype) sharSingleton
{
     if(!_instance) //防止频繁加锁
 
     @synchronized(self){
if(!_instance) { //防止创建多次
_instance = [[self   alloc]  init];
}
}
 
 
return  _instance;
}
 
 
2.1 一次性代码(dispatch_once);
 
<1>  在.m文件中保留一个全局的static的实例
 
static id _instance;
 
<2> 重写如若干方法(allocWithZone:和 copyWithZone:) 并提供一个类方法让外界访问唯一的实例
 
//(1)重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全).
 
+(id)allocWithZone:(struct _NSZone *)zone
{
     static dispatch_once_t  onceToken;
     dispatch_once(&onceToken,^{
     _instance = [super  allocWithZone:zone];
})
 
return  _instance;
}
 
//重写copyWithZone:方法
+(id)copyWithZone:(struct _NSZone)zone
{
     return  _instance;
}
 
 
//(3) 提供一个类方法让外界访问唯一的实例
+(instancetype) shareSingleton
{
     static  dispatch_once_t  onceToken;
     dispatch_once(&onceToken,^{
 
     _instance = [[self  alloc] init];
})
return  _instace;
}     
 
注意:在ARC 和MRC中单例的实现方式略有不同,MRC 下单例的实现比ARC 多了几个内存管理的方法;
 
MRC 中增加如下方法的实现
-(instancetype) retain {return  self;}
-(NSUInteger) retainCount {return  self;}
-(oneway void)release {}
-(instancetype)autorelease{return  self;}
 
3.判断当前环境(ARC/MRC)
 
#if__has_feature(objc_arc)
//ARC
#else 
     //MRC
#endif
 
4.注意两个方法
//面试问题:两个方法的区别?
<1> +(void)load;
//当类加载到OC运行环境(内存)中的时候,就会调用一次(一个类只会加载一次).
//程序一启动就会调用
//程序运行过程中,只会调用一次
<2>+(void)initialize;
//当第一次使用这个类的时候,(比如调用了类的某个方法)才会调用.
 
//并发程序一启动就会调用
 
 

多线程01

标签:

原文地址:http://www.cnblogs.com/R-X-L/p/4777433.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!