一、基本内容介绍:
二、线程分类:
1、pthread:
1)到入头文件: #import <pthread.h>
// 创建线程,并且在线程中执行 demo 函数
- (void)pthreadDemo {
/**
参数:
1> 指向线程标识符的指针,C 语言中类型的结尾通常 _t/Ref,而且不需要使用 *
2> 用来设置线程属性
3> 线程运行函数的起始地址
4> 运行函数的参数
返回值:
- 若线程创建成功,则返回0
- 若线程创建失败,则返回出错编号
*/
pthread_t threadId = NULL;
NSString *str = @"Hello Pthread";
int result = pthread_create(&threadId, NULL, demo, (__bridge void *)(str));
if (result == 0) {
NSLog(@"创建线程 OK");
} else {
NSLog(@"创建线程失败 %d", result);
}
}
// 后台线程调用函数
void *demo(void *params) {
NSString *str = (__bridge NSString *)(params);
NSLog(@"%@ - %@", [NSThread currentThread], str);
return NULL;
}
注:
2、NSThread
1.创建方式:
(1)NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(longOperation:) object:@"THREAD"];
[thread start];//方式1需要手动启动
(2)[NSThread detachNewThreadSelector:@selector(longOperation:) toTarget:self withObject:@"DETACH"];
(3)[self performSelectorInBackground:@selector(longOperation:) withObject:@"PERFORM"];
2.线程状态:
代码演示:
注意:不要在主线程用exit
3.线程属性
1.name 线程名称:通常需要在程序崩溃时,获取程序准确执行所在的线程
2.threadPriority 线程的优先级 优先级范围为0-1.0, 默认是0.5 建议不要使用优先级。避免程序出错;
>优先级只能保证CPU调度的可能性高,不见得会先调用;
>多线程的目的是:将耗时的操作放在后台。避免影响用户的交互和阻塞主线程
>开发原则:简单
3.stackSize 栈区大小: 无论主线程还是子线程,大小都是512k 设置线程大小必须是4的整数倍。最小为8k
4.isMainThread 是否为主线程
4.互斥锁
互斥锁:
1.保证锁内的代码,同一时间,只有一条线程能够执行!
2.互斥锁的锁定范围,应该尽量小,锁定范围越大,效率越差!(最好只包含读写操作)
3.能够加锁的任意 NSObject
对象
4.如果代码中只有一个地方需要加锁,大多都使用 self
,这样可以避免单独再创建一个锁对象
5.注意:锁对象一定要保证所有的线程都能够访问
5、自旋锁
自旋锁和互斥锁
相同点:能够保证同一时间,只有一条线程执行锁定范围的代码;
不同点:
互斥锁
:如果发现有其他线程正在执行锁定的代码,线程会进入休眠状态
,等待其他线程执行完毕,打开锁之后,线程会被唤醒
自旋锁
:如果发现有其他线程正在执行锁定的代码,线程会以死循环
的方式,一直等待锁定代码执行完成(适合简短的代码)
主线程
又被称为UI 线程
开发建议:
所有属性都声明为 nonatomic
尽量避免多线程抢夺同一块资源
尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力
6、线程间的通讯
在后台线程下载图像
[self performSelectorInBackground:@selector(方法名) withObject:nil];
在主线程设置图像
[self performSelectorOnMainThread:@selector(方法名) withObject: waitUntilDone:NO];