iOS 多线程
进程 与线程的区别
进程:资源分配的最小单位,进程中包含了某些资源的内存区域,一个正在运行的应用程序就相当于一个进程
线程:是进程的一个最小执行单元,CPU独立运行和调度的基本基本单元。
一个程序至少有一个进程,一个进程至少有一个线程。
多线程
通俗的讲:在一个进程中,开辟多条线程,同时执行任务
优点:
1.为了更好的利用cpu的资源,如果只有一个线程,则第二个线程必须等待第一个结束之后才能进行,如果使用多线程则在主线程执行任务的同时可以执行其他任务,而不需要等待
2.进程之间不可以相互通信,而线程之间可以。
3.可以将耗时的操作放在其他线程,主线程负责页面刷新使得应用程序更加流畅,用户体验更好
缺点
1.新建线程会占用更多的内存和cpu,线程太多会降低系统的总体性能,每个线程都需要在系统内核和程序的内存空间上申请内存,
2.共享资源的抢夺
生命周期
1.新建 New :实例化线程对象。
2.就绪Runanable: 向线程发送start消息,线程对象被加入线程池等待cpu进行调度。
3.运行Running:cpu负责调度执行,线程执行完成之前,状态可能会在就绪运行之间来回切换。就绪
4.堵塞:死锁:线程之间都在等待其他线程执行完任务,使得所有线程都处于等待时,导致线程阻塞。可适用休眠或锁,阻塞线程执行。
5.死亡 death:正常死亡,线程执行完毕。非正常死亡:满足某个条件后,在线程终止执行/在主线程终止线程对象。
cancel:取消。并不会直接取消线程,而是给线程对象添加一个isCancelled的标识
exit:退出,这个方法直接退出当前线程,后面的代码都不会执行。
OC创建多线程的方法
pthread
一套通用的多线程API,适用于Unix、Linux/Windows等系统。跨平台,可移植,使用难度大。 C语言开发,生命周期由程序员管理。
NSThread
一使用面向对象,简单易用,轻量级。 OC语言开发,生命周期由程序员管理。
基本用法
创建多线线程的三种方法
///主线程执行
[self performSelectorOnMainThread:@selector(mainThreadActionSEL) withObject:nil waitUntilDone:false];
///直接用block构建
NSThread *therad = [[NSThread alloc]initWithBlock:^{
for (int i = 0; i < 3; i++) {
//模拟耗时操作
[NSThread sleepForTimeInterval:1];
NSLog(@"%@",[NSThread currentThread]);
}
}];
[therad start];
//通过target构建
NSThread *anotherThread = [[NSThread alloc]initWithTarget:self selector:@selector(anotherThreadAction) object:nil];
[anotherThread start];
//隐式创建
[self performSelectorInBackground:@selector(background:) withObject:@"threadBackgroud"];
其他用法
//主线程
[NSThread mainThread];
//当前线程
[NSThread currentThread];
//判断当前是否是多线程
[NSThread isMultiThreaded];
//线程休眠
[NSThread sleepForTimeInterval:1];
//在指定时间休眠
[NSThread sleepUntilDate:[NSDate date]];
//退出线程
[NSThread exit];
//取消操作,并不会直接取消,而是给线程对象添加了一个cancelled表示
[[NSThread currentThread]cancel];
GCD
自动管理线程的生命周期,你只需要告诉GCD需要执行什么任务,不需要写任何线程管理的代码,会自动利用CPU更多的内核。
基本概念
任务:就是将任务封装好,放到block中,等待cpu调度去执行。
同步sync:按顺序执行,前一个不执行完,后面不能执行,不开启新线程
异步async:开启多条线程,同时执行不同的任务
队列:
主队列:主线程
串行:DISPATCH_QUEUE_SERIAL
线程只能依次有序的执行,按顺序排列,FIFO
并行:DISPATCH_QUEUE_CONCURRENT
,线程同时可以一起执行,实际上是cpu在多个线程之间快速的切换。
创建队列
///串行队列
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
///并行队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("CONCURRENT", DISPATCH_QUEUE_CONCURRENT);
同步串行
/*
同步串行 :在同一线程下按顺序进行 FIFO
*/
dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"dispatch1 :当前线程%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"dispatch2 :当前线程%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"dispatch3 :当前线程%@",[NSThread currentThread]);
});
同步并行
dispatch_queue_t queuqe = dispatch_queue_create("syncConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queuqe, ^{
NSLog(@"disatch1 :当前线程%@",[NSThread currentThread]);
});
dispatch_sync(queuqe, ^{
NSLog(@"disatch2 :当前线程%@",[NSThread currentThread]);
});
dispatch_sync(queuqe, ^{
NSLog(@"disatch3 :当前线程%@",[NSThread currentThread]);
});
异步串行
dispatch_queue_t queuqe = dispatch_queue_create("asyncConcurrentQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queuqe, ^{
NSLog(@"disatch1 :当前线程%@",[NSThread currentThread]);
});
dispatch_async(queuqe, ^{
NSLog(@"disatch2 :当前线程%@",[NSThread currentThread]);
});
dispatch_async(queuqe, ^{
NSLog(@"disatch3 :当前线程%@",[NSThread currentThread]);
});
NSOperation
NSOperation是Apple对GCD的封装,完全面向对象
优点:
1.可以取消未执行的operation
2.指定相同或不同队列的依赖关系
3.可以设置优先级
4.可以通过KVO监听当前线程的状态
5.重用operation,operation只能被执行一次后生命周期就结束了,不能被多次执行