目录
1. NSSthread简介
2. iOS中的使用
2.1 代码格式
2.2 线程属性
2.2.1 查看当前线程
2.2.2 修改线程名称
2.2.3 设置线程优先级
2.3 线程状态
一看到"NS",就知道这是专属于OC语言的,因此NSSthread是面向对象的一种实现多线程的技术方法。相比于pthread来说,其更容易理解,但由于生命周期依然需要由开发者手动管理,因此,用的也比较少。
// 第一种方法
NSThread *thread = [[NSThread alloc] initWithTarget:(nonnull id) selector:(nonnull SEL) object:(nullable id)];
[thread start];
// 第二种方法
NSThread *thread = [NSThread detachNewThreadSelector:(nonnull SEL) toTarget:(nonnull id) withObject:(nullable id)];
// 第三种方法
NSThread *thread = [NSThread detachNewThreadSelector:(nonnull SEL) toTarget:(nonnull id) withObject:(nullable id)];
示例
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread start];
// 查看viewDidLoad中的线程
NSLog(@"viewDidLoad %@",[NSThread currentThread]);
}
- (void)demo{
// 查看demo中的线程
NSLog(@"demo %@",[NSThread currentThread]);
}
运行结果
2018-11-22 21:24:17.017 NSThread演示[4289:280430] demo {number = 2, name = (null)}
2018-11-22 21:24:17.016 NSThread演示[4289:280376] viewDidLoad {number = 1, name = main}
结论
①number = 2, name = (null),说明demo方法是运行在子线程上的
②number = 1, name = main,说明viewDidLoad是运行在主线程上的,并且name = main很好的说明了这一点
示例
- (void)viewDidLoad {
[super viewDidLoad];
// 子线程1
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread1 start];
thread1.name = @"Sub_1";
// 子线程2
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread2 start];
thread2.name = @"Sub_2";
}
- (void)demo{
for (int i = 0; i < 10; i++){
// 查看demo中的线程
NSLog(@"demo 第%d次循环 %@",i,[NSThread currentThread]);
}
}
运行结果
2018-11-22 21:56:10.604 NSThread演示[4678:294580] demo 第0次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.605 NSThread演示[4678:294581] demo 第0次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.608 NSThread演示[4678:294580] demo 第1次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.610 NSThread演示[4678:294581] demo 第1次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.610 NSThread演示[4678:294580] demo 第2次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.610 NSThread演示[4678:294581] demo 第2次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.610 NSThread演示[4678:294580] demo 第3次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.611 NSThread演示[4678:294581] demo 第3次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.611 NSThread演示[4678:294580] demo 第4次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.611 NSThread演示[4678:294581] demo 第4次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.611 NSThread演示[4678:294580] demo 第5次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.718 NSThread演示[4678:294580] demo 第6次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.718 NSThread演示[4678:294581] demo 第5次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.718 NSThread演示[4678:294580] demo 第7次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.718 NSThread演示[4678:294581] demo 第6次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.718 NSThread演示[4678:294580] demo 第8次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.719 NSThread演示[4678:294581] demo 第7次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.719 NSThread演示[4678:294580] demo 第9次循环 {number = 2, name = Sub_1}
2018-11-22 21:56:10.720 NSThread演示[4678:294581] demo 第8次循环 {number = 3, name = Sub_2}
2018-11-22 21:56:10.725 NSThread演示[4678:294581] demo 第9次循环 {number = 3, name = Sub_2}
结论
①number = 2, name = Sub_1(number = 3, name = Sub_2),可以更改子线程名称
②对比上一个示例,可以看出线程的执行顺序是不确定的
③线程并不是同时执行的,而是在不停的来回切换执行
示例
- (void)viewDidLoad {
[super viewDidLoad];
// 子线程1
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread1 start];
thread1.name = @"Sub_1";
// 设置子线程1的优先级为最高
thread1.threadPriority = 1;
// 子线程2
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
[thread2 start];
thread2.name = @"Sub_2";
// 设置子线程2的优先级为最低
thread2.threadPriority = 0;
}
- (void)demo{
for (int i = 0; i < 20; i++){
// 查看demo中的线程
NSLog(@"demo 第%d次循环 %@",i,[NSThread currentThread]);
}
}
运行结果
2018-11-22 22:10:05.030 NSThread演示[4830:302059] demo 第0次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.032 NSThread演示[4830:302059] demo 第1次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.034 NSThread演示[4830:302059] demo 第2次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.035 NSThread演示[4830:302059] demo 第3次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.035 NSThread演示[4830:302059] demo 第4次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.036 NSThread演示[4830:302059] demo 第5次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.036 NSThread演示[4830:302059] demo 第6次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.037 NSThread演示[4830:302059] demo 第7次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.037 NSThread演示[4830:302059] demo 第8次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.037 NSThread演示[4830:302059] demo 第9次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.057 NSThread演示[4830:302059] demo 第10次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.058 NSThread演示[4830:302059] demo 第11次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.058 NSThread演示[4830:302059] demo 第12次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.059 NSThread演示[4830:302059] demo 第13次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.059 NSThread演示[4830:302059] demo 第14次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.060 NSThread演示[4830:302059] demo 第15次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.060 NSThread演示[4830:302059] demo 第16次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.060 NSThread演示[4830:302059] demo 第17次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.044 NSThread演示[4830:302060] demo 第0次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.061 NSThread演示[4830:302059] demo 第18次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.104 NSThread演示[4830:302059] demo 第19次循环 {number = 2, name = Sub_1}
2018-11-22 22:10:05.120 NSThread演示[4830:302060] demo 第1次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.122 NSThread演示[4830:302060] demo 第2次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.124 NSThread演示[4830:302060] demo 第3次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.133 NSThread演示[4830:302060] demo 第4次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.137 NSThread演示[4830:302060] demo 第5次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.137 NSThread演示[4830:302060] demo 第6次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.142 NSThread演示[4830:302060] demo 第7次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.151 NSThread演示[4830:302060] demo 第8次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.151 NSThread演示[4830:302060] demo 第9次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.152 NSThread演示[4830:302060] demo 第10次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.192 NSThread演示[4830:302060] demo 第11次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.193 NSThread演示[4830:302060] demo 第12次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.194 NSThread演示[4830:302060] demo 第13次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.200 NSThread演示[4830:302060] demo 第14次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.202 NSThread演示[4830:302060] demo 第15次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.203 NSThread演示[4830:302060] demo 第16次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.203 NSThread演示[4830:302060] demo 第17次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.204 NSThread演示[4830:302060] demo 第18次循环 {number = 3, name = Sub_2}
2018-11-22 22:10:05.204 NSThread演示[4830:302060] demo 第19次循环 {number = 3, name = Sub_2}
结论
①线程优先级的范围是[0,1],0优先级对低,1优先级最高
②优先级最高并不代表会先执行完再执行低的优先级,而是随机的,只是优先级大的出现的频率较高而已
注:图片来自互联网
①新建:在执行new(alloc init)操作后,会在内存中创建一个线程对象
②就绪:在调用start方法后,会把线程对象放入一个可调度线程池中,进入就绪状态,等着被CPU执行
③运行:CPU调度当前线程后进入运行状态,运行状态是不可控制的
④阻塞:调用了sleep方法或等待同步锁时,会进入阻塞状态,阻塞时,会把线程对象从可调度线程池中取出
⑤死亡:死亡一般有两种:自然死亡和非自然死亡。所谓自然死亡,就是线程任务执行完毕,正常结束;而非自然死亡,就是发生异常/强制退出了