您的位置:首页 > 职场人生

多线程必备宝典(持续更新)

2016-08-03 22:33 232 查看

一.多线程的原理,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;
}
}




二.GCD的概念

1.1 什么是GCD

Grand Central Dispatch (GCD) 是导步执行任务的技术之一。一般将应用程序中记述的线 程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue 中,GCD 就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部份 来实现,因为可统一管理,也可执行任务,就样就比以前的线程更有效率。

也就是说,GCD 用我们难以默念的非常的简洁的记述方法,实现了极为复杂繁琐的多 线程线程,可以说是一项目划时代的技术。

1.2 GCD的核心概念

将任务添加到队列,并且指定执行任务的函数
任务使用block封装,任务的block没有参数没有返回值
执行任务的函数

3.1 异步 dispatch_async
* 不用等待当前语句执行完毕,就可以执行下一个语句
* 会开启线程执行block 任务
* 异步是多线程的代名词

3.2 同步 dispatch_sync
* 必须等待当前语句执行完毕才可以执行下一条语句
* 不会开启线程
* 在当前线程执行 block 任务


队列-负责调度任务

4.1 串行队列

* 一次只能执行一个任务

4.2 并发队列

* 可同时执行多个任务

4.3 主队列

* 专门用来在主线程上调度任务的队列
* 不会开启线程,因为主线程是系统自动开启的
* 在主线程**有空闲**的时候,才会调度队列中的任务
* 如果当前是在主线程,不可以在同步函数中使用主队列,否则会造成一个死锁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息