多线程之-NSThread
介绍NSThread之前先介绍一下pthread,仅供了解,一般在开发中用不到的
pthread(了解)
- 类型:
- C语言中类型的结尾通常 _t/Ref,而且不需要使用 *
/*
参数说明:
1. pthread_t *restrict 线程代号的地址
2. const pthread_attr_t *restrict 线程的属性
3. 调用函数的指针
- void *(*)(void *)
- 返回值 (函数指针)(参数)
- void * 和 OC 中的 id 是等价的
4. void *restrict 传递给该函数的参数
返回值:
如果是0,表示正确
如果是非0,表示错误码
*/
NSString *str = @"lnj";
pthread_t thid;
int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));
if (res == 0) {
NSLog(@"OK");
} else {
NSLog(@"error %d", res);
}
NSThread
- 一个NSThread对象就代表一条线程
创建线程的几种方式:
- alloc/init
// 1.创建线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:@"lnj"];
// 设置线程名称
[thread setName:@"xmg"];
// 设置线程的优先级
// 优先级仅仅说明被CPU调用的可能性更大
[thread setThreadPriority:1.0];
// 2.启动线程
[thread start];
- 主线程相关用法
+ (NSThread *)mainThread; // 获得主线程
- (BOOL)isMainThread; // 是否为主线程
+ (BOOL)isMainThread; // 是否为主线程
获得当前线程
NSThread *current = [NSThread currentThread];
线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
- detach/performSelector
- 优点:简单快捷
- 缺点:无法对线程进行更详细的设置
// 1.创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"lnj"];
// 1.创建线程
// 注意: Swift中不能使用, 苹果认为这个方法不安全
// 隐式创建并启动线程
[self performSelectorInBackground:@selector(demo:) withObject:@"lnj"];
- 线程状态
控制线程状态
启动线程
- (void)start;
// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
阻塞(暂停)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 进入阻塞状态
//例:
// 睡眠5秒钟
[NSThread sleepForTimeInterval:5];
// 从当前时间睡3秒
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
强制停止线程
+ (void)exit;
// 进入死亡状态
注意:一旦线程停止(死亡)了,就不能再次开启任务
互斥锁
-
多线程的安全隐患
- 被锁定的代码同一时刻只能有一个线程执行
-
互斥锁使用格式:
@synchronized(锁对象)
{
// 需要锁定的代码
}
// 解锁
-
互斥锁的优缺点
- 优点:能有效防止因多线程抢夺资源造成的数据安全问题
- 缺点:需要消耗大量的CPU资源
-
互斥锁注意点
- 锁定1份代码只用1把锁,用多把锁是无效的
- 锁定范围越大, 性能越差
-
线程间的通信
- 在子线程中加载数据,回到主线程中刷新UI
-
原子和非原子属性
- atomic:线程安全,需要消耗大量的资源
- nonatomic:非线程安全,适合内存小的移动设备
-
自旋锁 & 互斥锁
- 共同点
- 都能够保证同一时间,只有一条线程执行锁定范围的代码
- 不同点
- 互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入"休眠"状态,等待其他线程执行完毕,打开锁之后,线程会被"唤醒"
- 自旋锁:如果发现有其他线程正在执行锁定的代码,线程会"一直等待"锁定代码执行完成! 自旋锁更适合执行非常短的代码
- 共同点