在iOS开发中,需要用到的多线程技术。
2016-07-03 22:48
330 查看
目录:
1、多线程的概念
2、多线程的执行原理
3、多线程的优缺点
4、什么是主线程?
5、iOS中有哪些多线程的技术方案
5.1pthread的简单使用
5.2NSThread的简单使用
6、线程的状态
7、多线程操作共享资源的问题
7、1资源抢夺问题的分析和解决
7、2什么是互斥锁,互斥锁的原理
8、什么是原子属性?
9、关于互斥锁和原子锁
10、补充
1、多线程的概念
要了解什么是多线程,首先必须知道什么是线程?什么是进程?
进程
进程是指在系统中正在运行的一个应用程序
每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存空间内
通过“活动监视器”可以查看Mac系统中所开启的进程
线程
1个进程可以有多个线程组成(1个进程至少要有1个线程)
线程是进程的基本执行单元,一个进程的所有任务都在线程中执行
2、多线程的执行原理
a. (单核CPU)同一时间,cpu只能处理1个线程,只有1个线程在执行任务
b.多线程同时执行:是CPU快速的在多个线程之间的切换
c.cpu调度线程的时间足够快,就造成了多线程的"同时"执行的假象
d. 如果线程数非常多,cpu会在n个线程之间切换,消耗大量的cpu资源
e. 每个线程被调度的次数会降低,线程的执行效率降低
3、多线程的优缺点
优点
能适当提高程序的执行效率
能适当提高资源的利用率(cpu,内存)
线程上的任务执行完成后,线程会自动销毁
缺点
开启线程需要占用一定的内存空间(默认情况下,每一个线程都占512KB)
如果开启大量的线程,会占用大量的内存空间,降低程序的性能
线程越多,cpu在调用线程上的开销就越大
程序设计更加复杂,比如多线程的数据共享、线程间的通信
下图为官方文档中的一个截图,需要注意的是,在iOS中主线程的栈空间也是512KB,通过控制台的打印我们也可以很容易得出,这个可能是Xcode文档更新不太及时。
4、什么是主线程?
一个程序运行后,默认会开启1个线程,称为“主线程”或“UI线程”
主线程一般用来 刷新UI界面 ,处理UI事件(比如:点击、滚动、拖拽等事件)
主线程使用注意
别将耗时的操作放到主线程中
耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种卡的坏体验
5、iOS中有哪些多线程的技术方案
5.1pthread的简单使用
代码:
pthread_t shabi;
// 创建一个子线程
int result = pthread_create(&shabi, NULL, demo, NULL);
if (result == 0) {
NSLog(@"创建成功,%@",[NSThread currentThread]);
}
else{
NSLog(@"失败");
}
// 这个方法是子线程执行的
void *demo(void *pram)
{
NSLog(@"创建成功,%@",[NSThread currentThread]);
return NULL;
}
5.2NSThread的简单使用
方式1
NSThread *thread = [[NSThread alloc] initWithTarget:selfselector:@selector(demo:) object:nil];
[thread start];
方式2
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:selfwithObject:nil];
方式3
[self performSelectorInBackground:@selector(demo:) withObject:nil];
6、线程的状态
6、1控制线程的状态
启动线程
- (void)start;
线程进入就绪状态,当线程执行完毕后自动进入死亡状态。
暂停(阻塞)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
线程进入阻塞状态
停止线程
+ (void)exit;
线程进入死亡状态
注意:一旦线程停止(死亡)了,就不能再次开启任务
6、2线程的属性
线程名称
设置线程名称可以当线程执行的方法内部出现异常的时候记录 异常和当前线程
线程优先级
内核调度算法在决定该运行哪个线程时,会把线程的优先级作为考量因素,较高优先级的线程会比较低优先级的线程具有更多的运行机会。较高优先级不保证你的线程具体执行的时间,只是相比较低优先级的线程,它更有可能被调度器选择执行而已。
7、多线程操作共享资源的问题
共享资源
资源 : 一个对象、一个变量、一个文件
共享资源 : 全局的对象,变量,文件.可以被其他对象访问的资源
在多线程的环境下,1块资源可能会被多个线程共享,也就是多个线程可能会操作同一块资源
当多个线程操作同一块资源时,很容易引发数据错乱和数据安全问题,数据有可能丢失,有可能增加,有可能错乱.
7、1资源抢夺问题的分析和解决
问题分析:
问题解决:
7、2什么是互斥锁,互斥锁的原理
互斥锁使用
@synchronized(锁对象) { // 需要锁定的代码 }
互斥锁
能有效防止因多线程抢夺资源造成的数据安全问题
相关专业术语:线程同步
线程同步的意思是:多条线程按顺序地执行任务
互斥锁,就是使用了线程同步技术
互斥锁原理
每一个对象(NSObject)内部都有一个锁(变量),当有线程要进入synchronized到代码块中会先检查对象的锁是打开还是关闭状态,默认锁是打开状态(1),如果是线程执行到代码块内部 会先上锁(0)。如果锁被关闭,再有线程要执行代码块就先等待,直到锁打开才可以进入。
线程执行到synchronized
i. 检查锁状态 如果是开锁状态(1)转到ii 如果上锁(0)转到v
ii. 上锁(0)
iii. 执行代码块
iv. 执行完毕 开锁(1)
v. 线程等待(就绪状态)
加锁后程序执行的效率比不加锁的时候要低,因为要线程要等待锁,但是锁保证了多个线程同时操作全局变量的安全性
8、什么是原子属性?
属性中的修饰符
nonatomic 非原子属性
atomic 原子属性(线程安全),针对多线程设计的,默认值
保证同一时间只有一个线程能够写入(但是同一个时间多个线程都可以取值)
单写多读:单个线程写入,多个线程可以读取
atomic 本身就有一把锁(自旋锁)
nonatomic和atomic对比
atomic:线程安全,需要消耗大量的资源
nonatomic:非线程安全,适合内存小的移动设备
iOS开发的建议
所有属性都声明为nonatomic
尽量避免多线程抢夺同一块资源
尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力
9、关于互斥锁和原子锁
互斥锁
如果发现其他线程正在执行锁定代码,线程会进入休眠(就绪状态),等其它线程时间片到打开锁后,线程会被唤醒(执行)
自旋锁
如果发现有其它线程正在锁定代码,线程会用死循环的方式,一直等待锁定的代码执行完成 自旋锁更适合执行不耗时的代码
10、补充
线程安全
多个线程同时操作共享资源是不安全的,多个线程同时操作一个全局变量
线程安全:在多个线程进行读写操作时,仍然能够保证数据的正确
主线程(UI线程)
几乎所有UIKit类库提供的类都是线程不安全的,所有更新UI的操作都在主线程上执行
所有包含NSMutable的类都是线程不安全的
1、多线程的概念
2、多线程的执行原理
3、多线程的优缺点
4、什么是主线程?
5、iOS中有哪些多线程的技术方案
5.1pthread的简单使用
5.2NSThread的简单使用
6、线程的状态
7、多线程操作共享资源的问题
7、1资源抢夺问题的分析和解决
7、2什么是互斥锁,互斥锁的原理
8、什么是原子属性?
9、关于互斥锁和原子锁
10、补充
1、多线程的概念
要了解什么是多线程,首先必须知道什么是线程?什么是进程?
进程
进程是指在系统中正在运行的一个应用程序
每个进程之间是独立的,每个进程均运行在其专用的且受保护的内存空间内
通过“活动监视器”可以查看Mac系统中所开启的进程
线程
1个进程可以有多个线程组成(1个进程至少要有1个线程)
线程是进程的基本执行单元,一个进程的所有任务都在线程中执行
2、多线程的执行原理
a. (单核CPU)同一时间,cpu只能处理1个线程,只有1个线程在执行任务
b.多线程同时执行:是CPU快速的在多个线程之间的切换
c.cpu调度线程的时间足够快,就造成了多线程的"同时"执行的假象
d. 如果线程数非常多,cpu会在n个线程之间切换,消耗大量的cpu资源
e. 每个线程被调度的次数会降低,线程的执行效率降低
3、多线程的优缺点
优点
能适当提高程序的执行效率
能适当提高资源的利用率(cpu,内存)
线程上的任务执行完成后,线程会自动销毁
缺点
开启线程需要占用一定的内存空间(默认情况下,每一个线程都占512KB)
如果开启大量的线程,会占用大量的内存空间,降低程序的性能
线程越多,cpu在调用线程上的开销就越大
程序设计更加复杂,比如多线程的数据共享、线程间的通信
下图为官方文档中的一个截图,需要注意的是,在iOS中主线程的栈空间也是512KB,通过控制台的打印我们也可以很容易得出,这个可能是Xcode文档更新不太及时。
4、什么是主线程?
一个程序运行后,默认会开启1个线程,称为“主线程”或“UI线程”
主线程一般用来 刷新UI界面 ,处理UI事件(比如:点击、滚动、拖拽等事件)
主线程使用注意
别将耗时的操作放到主线程中
耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种卡的坏体验
5、iOS中有哪些多线程的技术方案
5.1pthread的简单使用
代码:
pthread_t shabi;
// 创建一个子线程
int result = pthread_create(&shabi, NULL, demo, NULL);
if (result == 0) {
NSLog(@"创建成功,%@",[NSThread currentThread]);
}
else{
NSLog(@"失败");
}
// 这个方法是子线程执行的
void *demo(void *pram)
{
NSLog(@"创建成功,%@",[NSThread currentThread]);
return NULL;
}
5.2NSThread的简单使用
方式1
NSThread *thread = [[NSThread alloc] initWithTarget:selfselector:@selector(demo:) object:nil];
[thread start];
方式2
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:selfwithObject:nil];
方式3
[self performSelectorInBackground:@selector(demo:) withObject:nil];
6、线程的状态
6、1控制线程的状态
启动线程
- (void)start;
线程进入就绪状态,当线程执行完毕后自动进入死亡状态。
暂停(阻塞)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
线程进入阻塞状态
停止线程
+ (void)exit;
线程进入死亡状态
注意:一旦线程停止(死亡)了,就不能再次开启任务
6、2线程的属性
线程名称
设置线程名称可以当线程执行的方法内部出现异常的时候记录 异常和当前线程
线程优先级
内核调度算法在决定该运行哪个线程时,会把线程的优先级作为考量因素,较高优先级的线程会比较低优先级的线程具有更多的运行机会。较高优先级不保证你的线程具体执行的时间,只是相比较低优先级的线程,它更有可能被调度器选择执行而已。
7、多线程操作共享资源的问题
共享资源
资源 : 一个对象、一个变量、一个文件
共享资源 : 全局的对象,变量,文件.可以被其他对象访问的资源
在多线程的环境下,1块资源可能会被多个线程共享,也就是多个线程可能会操作同一块资源
当多个线程操作同一块资源时,很容易引发数据错乱和数据安全问题,数据有可能丢失,有可能增加,有可能错乱.
7、1资源抢夺问题的分析和解决
问题分析:
问题解决:
7、2什么是互斥锁,互斥锁的原理
互斥锁使用
@synchronized(锁对象) { // 需要锁定的代码 }
互斥锁
能有效防止因多线程抢夺资源造成的数据安全问题
相关专业术语:线程同步
线程同步的意思是:多条线程按顺序地执行任务
互斥锁,就是使用了线程同步技术
互斥锁原理
每一个对象(NSObject)内部都有一个锁(变量),当有线程要进入synchronized到代码块中会先检查对象的锁是打开还是关闭状态,默认锁是打开状态(1),如果是线程执行到代码块内部 会先上锁(0)。如果锁被关闭,再有线程要执行代码块就先等待,直到锁打开才可以进入。
线程执行到synchronized
i. 检查锁状态 如果是开锁状态(1)转到ii 如果上锁(0)转到v
ii. 上锁(0)
iii. 执行代码块
iv. 执行完毕 开锁(1)
v. 线程等待(就绪状态)
加锁后程序执行的效率比不加锁的时候要低,因为要线程要等待锁,但是锁保证了多个线程同时操作全局变量的安全性
8、什么是原子属性?
属性中的修饰符
nonatomic 非原子属性
atomic 原子属性(线程安全),针对多线程设计的,默认值
保证同一时间只有一个线程能够写入(但是同一个时间多个线程都可以取值)
单写多读:单个线程写入,多个线程可以读取
atomic 本身就有一把锁(自旋锁)
nonatomic和atomic对比
atomic:线程安全,需要消耗大量的资源
nonatomic:非线程安全,适合内存小的移动设备
iOS开发的建议
所有属性都声明为nonatomic
尽量避免多线程抢夺同一块资源
尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力
9、关于互斥锁和原子锁
互斥锁
如果发现其他线程正在执行锁定代码,线程会进入休眠(就绪状态),等其它线程时间片到打开锁后,线程会被唤醒(执行)
自旋锁
如果发现有其它线程正在锁定代码,线程会用死循环的方式,一直等待锁定的代码执行完成 自旋锁更适合执行不耗时的代码
10、补充
线程安全
多个线程同时操作共享资源是不安全的,多个线程同时操作一个全局变量
线程安全:在多个线程进行读写操作时,仍然能够保证数据的正确
主线程(UI线程)
几乎所有UIKit类库提供的类都是线程不安全的,所有更新UI的操作都在主线程上执行
所有包含NSMutable的类都是线程不安全的
相关文章推荐
- Python3写爬虫(四)多线程实现数据爬取
- C#实现多线程的同步方法实例分析
- 浅谈chuck-lua中的多线程
- C#简单多线程同步和优先权用法实例
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C#多线程编程中的锁系统(三)
- 解析C#多线程编程中异步多线程的实现及线程池的使用
- C#多线程学习之(六)互斥对象用法实例
- 基于一个应用程序多线程误用的分析详解
- C#多线程学习之(三)生产者和消费者用法分析
- C#多线程学习之(一)多线程的相关概念分析
- C#多线程之Thread中Thread.IsAlive属性用法分析
- 分享我在工作中遇到的多线程下导致RCW无法释放的问题
- C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法
- C#多线程传递参数及任务用法示例
- C#控制台下测试多线程的方法
- 21天学习android开发教程之SurfaceView与多线程的混搭
- Ruby 多线程的潜力和弱点分析
- C#中WPF使用多线程调用窗体组件的方法
- C#如何对多线程、多任务管理(demo)