知识点
1.理解线程的概念
2.NSThread的使用
3.NSOperation的使用
4.GCD的使用
5.线程锁,线程安全
===============================
1.多线程是一种实现多任务并发执行的技术,允许同时执行多个任务,能够更合理的利用CPU的资源,提高效率、防止用户界面卡顿。
在iOS中,所有的UI处理只能在主线程做。
什么是进程?
· 简单的说进程就是我们电脑上运行的一个个应用程序,每一个程序就是一个进程,并且每个进程之间是独立的,每个进程运行在其专用受保护的内存空间内(window系统可以通过任务管理器进行查看,Mac系统中可以通过活动监视器对其进行查看)
什么是线程?
· 通过上面的介绍我们知道了什么是进程,那么如何让进程运行起来,这个时候就要有线程了,也就是说每个应用程序想要跑起来,最少也要有一条线程存在,其实应用程序启动的时候我们的系统就会默认帮我们的应用程序开启一条线程,这条线程也叫做'主线程',或者'UI线程'
进程和线程之间的关系
· 线程是进行的执行单元,进程的所有任务都在线程中执行,举例来说:进程就好比公司中的一个个部门,线程则代表着部门中的同事,而主线程当然是我们的老板了,一个公司部能没有老板,一个程序不能没有线程其实都是一个道理.
什么是CPU?
· CPU(中央处理器,Central Processing Unit)是一块超大规模的集成电路,只要用来解释计算机指令以及处理计算机软件中的数据.
多线程的原理
· 同一时间,CPU值能处理一个线程,只有一条线程在执行,多线程指的就是多条线程同时执行,其实就是CPU快速的在多条线程之间的切换,如果CPU调度线程的时间足够快,那么就会造成多线程并发执行的假象,而当线程特别多的时候,那么CPU在多条切换的效率也就会下降,同时消耗大量的CPU资源,线程的执行效率也就会下降.
多线程优点
· 能适当提高程序的执行效率
· 能适当提高资源的利用率
多线程的缺点
· 开启线程需要占用一定的内存空间,如果开启大量的线程,则会占用大量的内存空间,降低程序的性能
· 线程越多,CPU在调度线程上得开销就越大,程序的设计上也就更加的复杂,因此不推荐开启太多的线程,一般开启2~5条为最佳(且用且珍惜);
主线程
· 也就是应用程序启动的时候,系统默认帮我们创建的线程,称之为'主线程'或者是'UI线程';
· 主线程的作用一般都是用来显示或者刷新UI界面例如:点击,滚动,拖拽等事件
IOS中多线程的实现方案
方案
简介
语言
线程生命周期
使用频率
pthread
· 一套通用的多线程API
· 适用于 Unix / Linux / Windows
· 跨平台\可移植
· 使用难度大
C
程序员管理
几乎不用
NSThread
· 使用更加面向对象
· 简单易用,可直接操作线程对象
OC
程序员管理
偶尔使用
GCD
· 旨在替代NSThread等线程技术
· 充分利用设备的多核
C
自动管理
经常使用
NSOperation
· 基于GCD(底层是GCD)
· 比GCD多了一些更简单实用的功能
· 使用更加面向对象
OC
自动管理
经常使用
===============================
2.NSThread线程控制
1).创建线程,并自动执行
[NSThread detachNewThreadSelector:@selector(doSomeThing) toTarget:self withObject:nil];
2).创建线程,不自动执行
[[NSThread alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];
3).设置线程名
thread.name = @"另一个线程";
4).执行线程
[thread start];
5).线程取消
[thread cancel];
6).函数内获取当前线程
[NSThread currentThread];
7).获取主线程
[NSThread mainThread];
7).线程休眠
[NSThread sleepForTimeInterval:1.0f]; // 休眠几秒
[NSThread sleepUntilDate:date]; // 休眠到指定时间
8).线程退出
[NSThread exit];
9).线程通信
[self performSelector:@selector(function) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
===============================
3.NSOperation,是以任务为中心的一种多线程技术,并不直接管理线程
1).NSOperation是抽象父类,不要直接使用,而应该使用它的子类
NSInvocationOperation
[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];
NSBlockOperation
[NSBlockOperation blockOperationWithBlock:^{}];
添加任务间的依赖关系,前者依赖于后者的完成,也就是后者执行完,前者才能执行,依赖关系需要放在添加到队列之前设置
[invocation addDependency:blockOperation];
如果有必要,可以让Operation取消
[invocation cancel];
2.NSOperationQueue,任务队列,NSOperation对象需要添加到队列里面才会执行
添加到队列里之后,自动会给每个NSOperation对象创建一个线程去执行
创建NSOperationQueue
[[NSOperationQueue alloc] init];
设置最大并发数
queue.maxConcurrentOperationCount = 1;
添加任务到队列里
[queue addOperation:blockOperation];
让队列里面,所有的Operation都取消
[queue cancelAllOperations];
获取当前线程对列
currentQueue
获取主线程对列
mainQueue
===============================
4.GCD是一套C语言的线程控制API,是NSOperation的底层实现,用Block来表示一个任务
1).创建队列
dispatch_queue_create("QF Queue", DISPATCH_QUEUE_CONCURRENT);
2).系统的队列
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 全局队列
dispatch_get_main_queue(); // 主线程队列
3).异步执行任务
dispatch_async(globalQuque, ^{});
4).创建分组
dispatch_group_create();
5).添加任务到分组,并执行
dispatch_group_async(group, globalQuque, ^{});
6).分组执行完的通知
dispatch_group_notify(group, mainQuque, ^{});
===============================
5.线程锁
1).方式1:
_lock = [[NSLock alloc] init];
[_lock tryLock];
[_lock unlock];
2).方式2:
@synchronized(self) {}
网友评论