标签:
1??pthread 几乎不用 生命周期:程序员管理
C语言,适用于Unix\Linux\Windows等系统,跨平台、可移植,使用不方便
2??NSThread 偶尔使用 生命周期:程序员管理
OC语言,使用更加面向对象,简单易用,可直接操作线程对象,用的比较多
// 方式1
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
// 线程属性
thread.name = @"yang";
// 线程优先级 0~1 默认是0.5 越大优先级越高 只是CPU调用的可能性高一点
thread.threadPriority = 1;
// 开启线程 调用start 线程进入就绪状态,只是标示此线程可以执行了,并不是立即执行,只有在CPU有空闲的时候才会执行
[thread start];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
thread2.name = @"chen";
[thread2 start];
// 方式2 相当于上边的两行代码 创建一个线程后自动调用start方法
// [NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
// 方式3
// [self performSelectorInBackground:@selector(test:) withObject:@"123"];
// 线程的几种状态
// 新生状态 创建一个线程
// 就绪状态 调用start方法
// 运行状态 不用我们管
// 阻塞状态 调用sleep方法
// 死亡状态 调用exit方法
// 睡5秒 当前线程进入阻塞状态
// [NSThread sleepForTimeInterval:5];
// 结束当前线程(死亡状态)
[NSThread exit];
3??GCD 纯C语言,会充分利用CPU的多核,自动管理线程的生命周期(创建、任务调度、销毁)
队列、延迟操作(dispatch_after)、Once、调度组
两个函数:
dispatch_sync(queue,block); 同步 将任务添加到队列,不会开启线程
dispatch_async(queue,block); 异步 将任务添加到队列,然后GCD管理的线程池中有空闲线程就会从队列中取出任务执行,只是开启线程,不会创建线程
GCD会自动将队列中得任务按先进先出的方式取出并交给对应线程执行
任务:要执行的操作(方法) block指定,即代码块
队列:存放任务的集合
串行队列:一个接一个的调度任务
并行队列:可以同时调度多个任务
主 队列:全局串行,由主线程串行调度任务,只有一个
全局队列:本质就是一个无名的并行队列,可以用异步执行的方式验证,发现输出无序,说明是并行队列
// 全局队列和并发队列的区别
// 并发队列有名称,可以跟踪错误;全局队列没有
// 在ARC中不需要考虑内存释放,在MRC中需要手动释放内存,并发队列是create创建出来的,在MRC中见到create就要release;全局队列不需要release(只有一个)
几种情况:
串行队列:不管怎么执行都是顺序执行的 串行队列一次只调度一个任务
如果开多个线程,不能保证串行队列顺序执行,所以只开一个线程
并行队列:
同步:不创建线程,在当前线程执行,顺序执行
异步:开启多个线程 执行无序 (队列仍然是顺序取出的,并行队列只是可以同时调度多个任务,开启多个线程 导致 无序执行,如果开一个线程还是顺序执行的)
主 队列:先执行主线程中的代码,再执行队列中的任务
同步:主线程上的代码和队列中的任务相互等待,形成死锁
如果主线程正在执行代码,就不调度任务,而同步执行是要调度任务在当前线程执行,相互等待就形成了死锁
异步:在主线程上顺序执行
解决死锁问题:放入异步执行
延迟操作:
//异步执行 演示延迟执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_global_queue(0, 0), ^{
NSLog(@"延迟操作----%@",[NSThread currentThread]);
});
Once:看单例
调度组:
// 有时候需要在多个异步任务都执行完成之后继续做某些事情 这个时候需要用到调度组
// 比如下载歌曲,等待多个歌曲都下载完成之后,转到主线程提示用户
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
// 调度组的原理
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//添加一个任务
dispatch_group_enter(group); // group计数+1
dispatch_async(queue, ^{
NSLog(@"mj.avi %@",[NSThread currentThread]);
dispatch_group_leave(group); // 任务执行完成后 group计数-1
});
//添加一个任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"111.avi %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
//添加一个任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
NSLog(@"3333.avi %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"over");
});
//阻塞当前执行
// dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"abc");
}
4??NSOperation 生命周期自动管理
// NSOperation 抽象类,没有提供实现,一般作为父类来用,来约束子类都具有共同的属性和方法
// 是OC语言中基于GCD的面向对象的封装,使用起来比GCD更加简单(面向对象)
// NSOperation子类
// NSInvocationOperation
// NSBlockOperation
// 自定义子类继承NSOperation,实现内部相应的方法
// NSInvocationOperation
// 两种方法
// 创建操作 调用start方法
// 创建操作 把操作添加到队列中去执行
- (void)test1{
// // 1 调用start方法执行 不经常使用
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
// NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(demo) object:nil];
// [op start];
// });
// 2 创建操作 添加到队列中执行
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (int i = 0; i < 10; i ++) {
//创建操作
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
//把操作添加到队列中 相当于GCD并行队列 异步执行 (内部执行和GCD一样)
// 开启多个线程 无序
[queue addOperation:op];
}
}
// NSBlockOperation
- (void)test2{
// // 队列
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// //创建一个操作
// NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"我是一个操作 %@",[NSThread currentThread]);
// }];
// //把操作添加到队列
// [queue addOperation:op];
// // 回调函数 当前操作完成之后做得事情
// [op setCompletionBlock:^{
// NSLog(@"我是回调函数 %@",[NSThread currentThread]);
// }];
// // 队列
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//
// for (int i = 0; i < 20; i ++) {
// NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"%d %@",i,[NSThread currentThread]);
// }];
// [queue addOperation:op];
// }
// // 更方便的操作
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// for (int i = 0 ; i<20; i++) {
// //内部会帮我们创建操作,并把操作添加到队列中
// [queue addOperationWithBlock:^{
// NSLog(@"%d %@",i,[NSThread currentThread]);
// }];
// }
// 使用全局队列(队列属性)
for (int i = 0; i < 20; i ++) {
[self.queue addOperationWithBlock:^{
NSLog(@"%d %@",i,[NSThread currentThread]);
}];
}
}
// 设置最大并发数
_queue.maxConcurrentOperationCount = 2;
// 暂停 正在执行的任务会执行完成 后续的任务暂停
self.queue.suspended = !self.queue.isSuspended;
// 取消所有操作 会设置当前队列中所有的操作的canceled属性为yes
[self.queue cancelAllOperations];
// 操作之间依赖关系
- (void)test2{
//模拟软件升级 下载 解压 通知用户
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载 %@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:2];
NSLog(@"解压 %@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"通知用户 %@",[NSThread currentThread]);
}];
//设置 操作 之间的依赖关系 依赖关系可以跨操作队列
[op2 addDependency:op1];
[op3 addDependency:op2];
// [op1 addDependency:op3];
//把操作添加到队列中 并行队列 异步执行
[self.queue addOperations:@[op2,op1] waitUntilFinished:NO];
[[NSOperationQueue mainQueue] addOperation:op3];
NSLog(@"over");
}
// GCD 和 NSOperation的对比
// GCD是iOS4.0 推出的,主要针对多核cpu做了优化,是C语言的技术
// GCD是将任务(block)添加到队列(串行/并行/全局/主队列),并且以同步/异步的方式执行任务的函数
// GCD提供了一些NSOperation不具备的功能
// 一次性执行
// 延迟执行
// 调度组
// NSOperation是iOS2.0推出的,iOS4之后重写了NSOperation
// NSOperation将操作(异步的任务)添加到队列(并发队列),就会执行指定操作的函数
// NSOperation里提供的方便的操作
// 最大并发数
// 队列的暂定/继续
// 取消所有的操作
// 指定操作之间的依赖关系(GCD可以用同步实现)
标签:
原文地址:http://www.cnblogs.com/sunshineandsand/p/4602178.html