多线程必备宝典(持续更新)
来源:互联网 发布:php开发实战教程 编辑:程序博客网 时间:2024/06/09 23:09
一.多线程的原理,NSThread:
1.线程状态
1.1 线程状态运行过程
1.2 线程状态解释
- 新建
- 实例化线程对象
就绪
- 向线程对象发送 start 消息(调用start方法),线程对象被加入可调度线程池,等待CPU调度
- detachNewThreadSelector 方法和 performSelectorInBackground 方法会直接实例化一个线程对象,并加入到可调用线程池中,等待CPU的调度,不需要我们再去调用start方法
运行
- CPU 负责调用可调度线程池中的线程
- 线程完之前,状态会在就绪和运行之间来回切换,因为CPU不会执行完某个线程之后才去执行其他的线程
- 就绪和运行之间的状态变化由CPU来决定,程序员无法干预
阻塞
4.1. 当线程满足某些条件的时候,可以使用休眠或者锁阻塞线程的操作- sleepForTimeInterval 休眠指定时长
- sleepUntilDate 休眠到指定日期
- @synchronized(self) 互斥锁
死亡
5.1. 正常死亡- 线程执行完成之后
5.2. 非正常死亡
- 当满足某个条件之后,在线程内部中止执行
- 当满足某个条件之后,在其他线程中中止线程对象
2.线程安全
2.1 资源共享
- 生活中很多地方都存在线程资源共享的例子,比如:抢票,存钱
2.2 资源共享的影响
- 以下是在没有处理的情况下
- 在抢票分配痛苦过个中,造成两个人,甚至多个人购买同一张票
- 取钱过程中可能造成余额错误
- 抽奖活动造成多人中奖
2.3 解决办法 - 互斥锁
2.3.1 互斥锁介绍
- 语法
@synchronized(self) { }
作用
保证同一段代码,在同一时间内,只能在一个线程里面执行。在第一个线程进来的时候会对代码进行上锁,而第一个线程执行完之后会把锁打开,这个时候别的线程才会进来执行代码。
影响
效率变慢
- 注意点
互斥锁里面应尽量放少的代码,把读写的代码放到锁里面即可 - 锁对象
锁对象就是一个能加锁的NSObject 对象,锁一定是全局的,否则会锁不住,无法进行保存。一般情况下我们使用self 就当作锁对象即可
2.4 示例代码
- (void)saleTicket { while (YES) { [NSThread sleepForTimeInterval:1.0]; /** 1. 互斥锁为了保证同一资源在同一时间内,只能在一线程里使用 2. 别的线程想要使用同一个资源,必须等待另一个线程执行完成。完成后开锁了才可以使用 3. 使用互斥锁会消耗更多资源 */ @synchronized(self) { if (self.ticket > 0) { NSLog(@"%@--%zd",[NSThread currentThread],self.ticket); self.ticket --; continue; } } break; } }
@synchronized(self) { }
作用
保证同一段代码,在同一时间内,只能在一个线程里面执行。在第一个线程进来的时候会对代码进行上锁,而第一个线程执行完之后会把锁打开,这个时候别的线程才会进来执行代码。
影响
效率变慢
互斥锁里面应尽量放少的代码,把读写的代码放到锁里面即可
锁对象就是一个能加锁的NSObject 对象,锁一定是全局的,否则会锁不住,无法进行保存。一般情况下我们使用self 就当作锁对象即可
- (void)saleTicket { while (YES) { [NSThread sleepForTimeInterval:1.0]; /** 1. 互斥锁为了保证同一资源在同一时间内,只能在一线程里使用 2. 别的线程想要使用同一个资源,必须等待另一个线程执行完成。完成后开锁了才可以使用 3. 使用互斥锁会消耗更多资源 */ @synchronized(self) { if (self.ticket > 0) { NSLog(@"%@--%zd",[NSThread currentThread],self.ticket); self.ticket --; continue; } } break; } }
二.GCD的概念
1.1 什么是GCD
Grand Central Dispatch (GCD) 是导步执行任务的技术之一。一般将应用程序中记述的线 程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue 中,GCD 就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部份 来实现,因为可统一管理,也可执行任务,就样就比以前的线程更有效率。
也就是说,GCD 用我们难以默念的非常的简洁的记述方法,实现了极为复杂繁琐的多 线程线程,可以说是一项目划时代的技术。
1.2 GCD的核心概念
- 将任务添加到队列,并且指定执行任务的函数
- 任务使用block封装,任务的block没有参数没有返回值
- 执行任务的函数
3.1 异步 dispatch_async
3.2 同步 dispatch_sync* 不用等待当前语句执行完毕,就可以执行下一个语句 * 会开启线程执行block 任务 * 异步是多线程的代名词
* 必须等待当前语句执行完毕才可以执行下一条语句 * 不会开启线程 * 在当前线程执行 block 任务
队列-负责调度任务
4.1 串行队列* 一次只能执行一个任务
4.2 并发队列
* 可同时执行多个任务
4.3 主队列
* 专门用来在主线程上调度任务的队列 * 不会开启线程,因为主线程是系统自动开启的 * 在主线程**有空闲**的时候,才会调度队列中的任务 * 如果当前是在主线程,不可以在同步函数中使用主队列,否则会造成一个死锁
1 0
- 多线程必备宝典(持续更新)
- IOS面试宝典(一)(持续更新)
- IntelliJ IDEA 必备插件(持续更新...)
- Linux常用命令总结,持续更新,菜鸟必备
- 《程序员面试宝典》之错误纰漏(持续更新。。。)
- 对程序员面试宝典作一些总结--持续更新
- IOS面试宝典(二)(持续更新)-描述UIViewController的生命周期
- 多线程相关的一些术语 (持续更新)
- linux系统必备软件安装(持续更新)
- android进阶必备案例(小案例)(持续更新)
- 程序员必备网站大收集(持续更新)
- Android Studio 必备插件汇总(持续更新中......)
- 谷歌浏览器必备扩展插件(持续更新)
- 编程必备宝典
- 编程必备宝典
- 网络管理员必备宝典
- Net面试必备宝典
- IT(计算机/软件/互联网)专业词汇宝典(持续更新中)
- Oracle中TO_DATE TO_CHAR格式
- ListView实现城市快速索引功能
- 总结几个月来的学习内容,梳理学习思路
- notifyDataSetChanged ListView 不刷新
- 自造的多tab页情况下的切换
- 多线程必备宝典(持续更新)
- 顺序表应用6:有序顺序表查询
- 各种排序算法的总结和比较
- Simple UI Component
- Java NIO框架Netty简单使用
- Android从Fragment中跳转到Activity
- Educational Codeforces Round 14 C 好东西啊!!!
- 二分_B
- Spring(1)--初识Spring之HelloWorld