1.进程
- 一个APP应用就是一个进程
- iOS是单进程,安卓可以多进程
- 一个进程内可以有多个线程
2.多线程
优点:
- 能适当提高程序的执行效率
- 能适当提高资源利用率(CPU,内存)
- 线程上的任务执行完成后,线程会自动销毁
缺点:
- 开启线程需要占用一定的内存空间(默认情况下,每一个线程都占512KB)
- 如果开启大量的线程,会占用大量的内存空间,降低程序的性能
- 线程越多,CPU在调用线程上的开销就越大
- 程序设计更加复杂,比如线程间的通信、多线程的数据共享
3.线程的生命周期
就绪 -> 运行
运行 -> 就绪
线程之间的切换
多核就是并发
线程不能start 两次
4. 锁
推荐使用NSLock
偷懒用@synchronized
美滋滋
- 自旋锁
一个完成 下一个直接进去- 互斥锁
如果发现前面有线程在执行,就休眠
5.栅栏函数
他能够保证顺序执行,并保证线程安全
注意点:
- 栅栏函数一定要是自定义的并发队列,不能使用dispatch_get_global_queue(全局并发队列),因为全局并发队列跟自定义并发队列唤醒的方式不一样,并且系统也在使用全局并发队列,如果栅栏了全局并发队列也就栅栏住了系统的操作堵住
- 必须要求都在一个自定义队列里
- 不利于封装
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//AFN自有队列 -- @"com.almofire.cn.session"
[self.manager request1];
});
//AFN内有自己的队列 所以这里栅栏函数无效
dispatch_barrier_async(dispatch_get_global_queue(0, 0), ^{
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self.manager request2];
});
6.队列图
7.dispatch_group(组)
确保dispatch_group_enter跟dispatch_group_leave成组出现
//写法1
dispatch_group_enter(g);
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_group_leave(g);
});
//写法2(推荐)
dispatch_group_async(g, dispatch_get_main_queue(), ^{
});
//最终通知
dispatch_group_notify(t, dispatch_get_main_queue(), ^{
//只有当所有dispatch_group_enter跟dispatch_group_leave成组出现的时候才会进来
});
7.dispatch_semaphore(信号量)
能够控制并发数量
//创建信号量指定信号量的大小
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{
//发送信号量 信号量的值+1
dispatch_semaphore_signal(sem);
});
//等待信号量 当信号量为0一直等待(阻塞当前线程) 当值大于1 就会进行-1
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
注意点:
//崩溃
//初始值2
dispatch_semaphore_t sem = dispatch_semaphore_create(2);
//当前值1
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
原因:
dsema->dsema_value = value;//当前信号量的值
dsema->dsema_orig = value;//信号量的初始值
当前信号量的值是否小于初始值,如果是就崩溃