ios多线程操作(二)—— NSThread的应用
来源:互联网 发布:洮南幼儿带网络监控的 编辑:程序博客网 时间:2024/06/05 10:08
一、基本使用
1、三种创建子线程的方法
(1)NSThread直接创建,一个NSThread对象就代表一条线程
//实例化一个 NSThread对象 NSThread *t1 = [[NSThreadalloc]initWithTarget:selfselector:@selector(longOperation:)object:@"NSThread"]; // 启动线程 [t1 start];
自定义一个耗时操作:
//耗时操作- (void)longOperation:(id)obj { for (int i = 0; i < 10; ++i) { NSLog(@"%@ %d -- %@", [NSThreadcurrentThread], i, obj); }}
(2)、创建线程后自动启动线程
// "隐式"的多线程方法!跟 detach 类方法类似,可以直接开启线程执行方法! [selfperformSelectorInBackground:@selector(longOperation:)withObject:@"perform"];
该方法不需要调用start方法
(3)隐式创建并启动线程
// performSelectorInBackground可以让任意一个 NSObject都具有在后台执行线程的能力! // 会让代码写起来非常灵活!NSObject *obj = [[NSObjectalloc]init][obj performSelectorInBackground:@selector(loadData)withObject:nil];
2、主线程相关用法
+ (NSThread*)mainThread;// 获得主线程- (BOOL)isMainThread;// 是否为主线程+ (BOOL)isMainThread;// 是否为主线程
3、获得当前线程
NSThread*current = [NSThreadcurrentThread];
修改主线程的栈区大小:
//修改主线程的栈区大小 => 1M [NSThreadcurrentThread].stackSize = 1024 * 1024;
4、线程的调度优先级
+ (double)threadPriority;+ (BOOL)setThreadPriority:(double)p;- (double)threadPriority;- (BOOL)setThreadPriority:(double)p;
优先级的取值范围为0.0-1.0,线程默认优先级是0.5,最高是1.0。
优先级高只能说明 CPU 在调度的时候,会优先调度,并不意味着优先级低的就不被调用或者后调用!
在多线程开发的时候,不要去做不同线程之间执行的比较!线程内部的方法都是各自独立执行的,如果设置了优先级,那么就会有可能出现低优先级的线程阻塞高优先级的线程,也就是优先级反转!在ios开发中,多线程最主要的目的就是把耗时操作放在后台执行
5、为线程设置名字
- (void)setName:(NSString*)n;- (NSString*)name;
二、线程状态
每一个新建出来的线程被添加到可调度线程池中时就会处于就绪(runnable)状态,当CPU调度当前线程时,该线程会处于运行(running)状态,如果调用了sleep方法或者是等待同步锁时,该线程就会被移出可调度线程池,此时该线程处于阻塞(blocked)状态,当该线程sleep时间到时或得到同步锁又会被移入可调度线程池,此时该线程又处于就绪状态,当线程任务执行完毕或者异常强制退出时,该线程会处于死亡(dead)状态,如下图
启动线程:
- (void)start;
此时线程从就绪状态到运行状态
阻塞线程
+ (void)sleepUntilDate:(NSDate*)date;+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
进入阻塞状态
强制停止线程
+ (void)exit;
此方法不会给任何机会去清理线程执行过程中分配的资源,也就是说一旦退出当前线程,后续所有代码不会执行(若后续代码中又释放内存的操作,那会相当的危险,会造成内存泄露),当使用C语言分配内存的时候要在该方法前适当的释放内存。
三、资源抢夺
多线程会有安全隐患。1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件,当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。
如何解决隐患问题——使用互斥锁
假如有一个买票系统:
- (void)saleTickets { while (YES) { // 模拟延时 [NSThreadsleepForTimeInterval:1.0]; @synchronized(self) { // 确认是否还有票(读取的动作) if (self.tickets > 0) { // 卖一张(写入动作) self.tickets--; // 输出剩余票数 NSLog(@"剩余票数 %d %@", self.tickets, [NSThreadcurrentThread]); } else { NSLog(@"没票了 %@", [NSThreadcurrentThread]); break; } } }}
互斥锁的参数:
1、self 本质上是任意一个 NSObject 都可以当成锁!
2、 锁对象必须能够保证所有线程都能够访问(所以不可能是某个线程中的局部变量)
3、 如果在程序中,只有一个位置需要加锁,可以使用self对象
使用互斥锁的效果就是卖票正确了,但效率却是下降了,在ios开发中尽量不要区抢夺资源,也不要区使用同步锁
四、原子属性,互斥锁与自旋锁
(1)原子属性
nonatomic : 非原子属性
atomic :原子属性,是默认属性
* 是在多线程开发时,保证多个线程在"写入"的时候,能够保证只有一条线程执行写入操作!
* 是一个单(线程)写多(线程)读的多线程技术
* 原子属性,解决不了卖票问题,因为卖票的读写都需要锁定
* 有可能会出现"脏数据",重新读取一下就可以!
* 原子属性内部也有一把"锁"
* 原子属性的锁的性能要比互斥锁高!
(2)自旋锁与互斥锁
每一个原子属性里面都会有一个锁,称之为自旋锁
共同点:
都是保证同一时间,只有一条线程能够执行锁定范围的代码
区别:
互斥锁:如果发现代码已经被(其他线程)锁定,当前线程会进入休眠状态,等锁解除之后,重新被唤醒
自旋锁:如果发现代码已经被(其他线程)锁定,当前线程会以死循环的方式,一直判断锁是否解除,一旦接触立即执行!该锁,适合锁定非常短的代码,能够保证更高的执行性能!
互斥锁性能很差,在开发中很少用,只要是用到锁,性能都不高
(3) 线程安全
如果一个属性,在多个线程执行的情况下,仍然能够保证得到正确的结果,就叫做线程安全!要实现线程安全,就必须要使用到"锁"-> 性能不好!
iso开发中UI 线程有个约定,所有UI更新,都需要在主线程上执行!
原因:UIKit不是线程安全的!就是为了得到更高的性能!
0 0
- ios多线程操作(二)—— NSThread的应用
- ios多线程操作(二)—— NSThread的应用
- iOS 多线程(二)NSThread
- iOS多线程编程(二)------ NSThread
- iOS开发—iOS多线程编程之NSThread的使用
- iOS多线程技术的深度探究二: NSThread多线程技术
- 多线程编程(二)NSThread的使用
- iOS —— NSThread、NSOperation、GCD多线程的优缺点
- iOS多线程开发——NSThread的简单运用
- iOS开发多线程篇—NSThread及线程的状态
- iOS多线程学习(2)——NSThread和NSOperation
- IOS多线程之——NSThread
- iOS开发——多线程NSThread
- iOS多线程开发——NSThread浅析
- iOS开发—使用NSThread实现多线程
- iOS多线程(二) 实现方案上(pthread,NSThread介绍)
- iOS开发--多线程编程(二)NSThread买票
- iOS多线程的NSThread 方法
- 膄荿螈螄羃节螄羃芆芄蒇虿
- 子父类中变量的特点
- atitit. 文件上传带进度条 atiUP 设计 java c# php
- Java c 8
- TCP--RST复位攻击
- ios多线程操作(二)—— NSThread的应用
- final关键字
- Android-overridePendingTransition+Fragment
- SkipList跳表
- 顺序线性表的c++实现
- 有这样一个三位数,在其后面补上三个数字,使之变成一个六位数,这个六位数减去原来的三位数······
- 命令行执行java程序
- POJ-2078(dfs + 剪枝)
- Vim快捷键操作