一、多线程的基本概念理解
(1)进程:可以理解成一个运行中的应用程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础,主要管理资源。
(2)线程:是进程的基本执行单元,一个进程对应多个线程。
(3)主线程:处理UI,所有更新UI的操作都必须在主线程上执行。不要把耗时操作放在主线程,会卡界面。
(4)多线程:在同一时刻,一个CPU只能处理1条线程,但CPU可以在多条线程之间快速的切换,只要切换的足够快,就造成了多线程一同执行的假象。
(5)线程就像火车的一节车厢,进程则是火车。车厢(线程)离开火车(进程)是无法跑动的,而火车(进程)至少有一节车厢(主线程)。多线程可以看做多个车厢,它的出现是为了提高效率。
(6)多线程是通过提高资源使用率来提高系统总体的效率。
(7)我们运用多线程的目的是:将耗时的操作放在后台执行!
二、多线程的四种解决方案分别是:pthread,NSThread,GCD, NSOperation。
三、这里主要介绍一下GCD 的使用
(1):GCD的特点
GCD会自动利用更多的CPU内核
GCD自动管理线程的生命周期(创建线程,调度任务,销毁线程等)
程序员只需要告诉 GCD 想要如何执行什么任务,不需要编写任何线程管理代码
(2)GCD的基本概念
任务(block):任务就是将要在线程中执行的代码,将这段代码用block封装好,然后将这个任务添加到指定的执行方式(同步执行和异步执行),等待CPU从队列中取出任务放到对应的线程中执行。
同步(sync):一个接着一个,前一个没有执行完,后面不能执行,不开线程。
异步(async):开启多个新线程,任务同一时间可以一起执行。异步是多线程的代名词
队列:装载线程任务的队形结构。(系统以先进先出的方式调度队列中的任务执行)。在GCD中有两种队列:串行队列和并发队列。
并发队列:线程可以同时一起进行执行。实际上是CPU在多条线程之间快速的切换。(并发功能只有在异步(dispatch_async)函数下才有效)
串行队列:线程只能依次有序的执行。
GCD总结:将任务(要在线程中执行的操作block)添加到队列(自己创建或使用全局并发队列),并且指定执行任务的方式(异步dispatch_async,同步dispatch_sync)
//串行队列
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
//并行队列
dispatch_queue_t queue1 = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
//主队列:
dispatch_get_global_queue(0, 0)
//主线程
dispatch_get_main_queue()
//同步执行任务
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
// 任务放在这个block里
NSLog(@"我是同步执行的任务");
});
//异步执行任务
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 任务放在这个block里
NSLog(@"我是异步执行的任务");
});
//队列创建
//串行队列创建
dispatch_queue_t queue =dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
// 同步执行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行同步1 %@",[NSThread currentThread]);
}
});
//栅栏
dispatch_barrier_async(queue, ^{
NSLog(@"------------barrier------------%@", [NSThread currentThread]);
NSLog(@"******* 并发异步执行,在异步执行中加入一道分水岭,前面是先完成的,后面的 后完成 *********");
});
//线程组
- (void)testGroup {
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"队列组:有一个耗时操作完成!");
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"队列组:有一个耗时操作完成!");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"队列组:前面的耗时操作都完成了,回到主线程进行相关操作");
});
}
通常情况下的 多线程 常规操作是 异步加载主队列任务,在主队列里面加载耗时操作,等结束后回到主线程刷新界面
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 耗时操作放在这里
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程进行UI操作
});
});