多线程

多线程概述

进程:

正在活动(运行的)一个应用程序 就是一个进程

线程:

程序中独立运行的代码段

每一个进程都至少有1条线程 叫主线程 除了主线程以外的 都叫子线程

每一个线程 都是独立的 可以执行任务

子线程可以有 很多个 但是线程是耗费资源的(一般最多不超过5条 注:3条最佳)

程序退出后 会清空线程的任务

主线程可以操作什么样的任务?

UI界面 按钮点击 屏幕的滚动(一切用户看的见的 都要在主线程中去操作 不然就会出现听主线程还是子线程的问题)

子线程可以操作什么样的任务

比较大的耗时操作 又或者 用户看不到的操作 可以放到子线程当中去做 比如下载 解压缩 读取大型数据等 可以在子线程中操作

多线程的原理:

CPU在工作时,同一时间只能执行一个任务 之所以可以造成多条线程一起执行任务的假象 是因为CPU在线程之间进行高速的切换(调度)来达到多个任务一起执行的效果

多线程的优点:

  1. 可以提高执行任务的效率
  2. 可以让用户 有更好的用户体验

多线程的缺点:

如果大量的开辟的线程 会造成程序的卡顿 耗费过量的资源

物极必反 盛极而衰

多线程实现种类

  • NSObject
  • NSThread
  • NSOperationQueue
  • GCD

NSObject

开辟子线程去执行downLoad:方法 方法是NSObject的 所以一切对象都能够调用

[self performSelectorInBackground:@selector(downLoad:) withObject:@"123"];

子线程完成任务后: 比如请求完数据后 需要回到主线程在UI上面显示

waitUntilDone 是否等待回到主线程的方法执行完毕后 再向下执行

法一:

[self performSelectorOnMainThread: withObject: waitUntilDone:NO];

法二:

[self performSelector: onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];

NSThread

开辟子线程法一:

[NSThread *thread = [NSThread alloc] initWithTarget: selector: object:];
[thread start];

开辟子线程法二:

[NSThread detachNewThreadSelector: toTarget: withObject:];

NSThread的其他方法:

// 获取当前线程
[NSThread currentThread]

// 线程休眠(延迟执行)
[NSThread sleepForTimeInterval:10]

// 立即结束当前线程
// 相当于 你在这里 写了return
// 只要退出当前的线程 后面的一切方法 都不执行了
[NSThread exit];

// 判断当前线程是否为主线程
[NSThread isMainThread]

NSOperation

NSOperation是一个抽象类 他有两个子类: NSInvocationOperation NSBlockOperation

这两个子类都可以开辟子线程去完成某一任务 但是这些任务需要加入到 NSOperationQueue的队列中才能够执行

NSInvocationOperation

// 创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 给队列提供一个 可以设置的 最大并发数
// 一次最多并发执行2个任务
queue.maxConcurrentOperationCount = 2;

// 开启一个线程(相当于一个任务)
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downLoad:) object:@"123"];

// 将任务添加到队列中 
// 并不是添加一个队列 就开辟一个新线程 线程如何安排靠系统决定(优化)
[queue addOperation:operation];

// 另一种添加方法
[queue addOperationWithBlock:^{

        // block中 就是你要添加的任务
}];

NSBlockOperation

// 创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 给队列提供一个 可以设置的 最大并发数
// 一次最多并发执行2个任务
queue.maxConcurrentOperationCount = 2;

// 初始化一个任务
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

        // 添加的任务            
}];

[queue addOperation:blockOperation];

GCD

队列类型:

  1. 并行队列 系统提供了一个全局的并行队列(整个应用都可以使用)
  2. 串行队列 需要创建一个出来

任务:

  1. 同步: 不具备开启子线程能力
  2. 异步: 具备开启子线程能力

分四种情况

  1. 并行 – 异步任务
  2. 并行 – 同步任务
  3. 串行 – 异步任务
  4. 串行 – 同步任务

并行队列处理异步任务

结果: 多个子线程同时处理多个任务

// 获取 全局的并发队列
// dispatch_queue_t 队列的类型
// 参数1 是CPU切换的频率高度(切换的优先级)
// 参数2 是个预留参数 可以填0
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 添加异步任务
// 参数1 给哪个队列添加任务
dispatch_async(queue, ^{

        // 添加任务 

});

并行队列处理同步任务

结果: 主线程依次处理任务(相当于串行队列)

// 创建一个 并行队列
// 参数1 队列的标识符 反向域名 com.lanou3g.www
// 参数2 填 你要创建的队列的类型(串/并)
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_CONCURRENT);

// 添加同步任务
dispatch_sync(queue, ^{

        // 添加任务
});

// 创建的队列是需要释放的(ARC 不用释放)
dispatch_release(queue);

串行队列处理异步任务

结果: 某一个子线程处理串行任务

// 创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_SERIAL);

// 添加异步任务  
dispatch_async(queue, ^{

    // 添加任务

});

// 创建的队列是需要释放的(ARC 不用释放)
dispatch_release(queue);

串行队列处理同步任务

结果: 同2

dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.www", DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

        // 添加任务
        // 完成任务后回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{

            // 回到主线程 要执行的任务
            // 刷新UI

        });

});

// 创建的队列是需要释放的(ARC 不用释放)
dispatch_release(queue);

线程锁

法1:

 @synchronized(self) {

    // 需要上锁的代码

 }

法2:

self.lock = [[NSLock alloc] init];

[lock lock];

// 需要上锁的代码

[lock unlock];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值