我们在APP开发过程中, 很多情况下会碰到多个网络请求同时存在的要求, 这对我们开发者来说一般会有网络请求之间是否存在依赖关系, 即:上个网络请求结果有没有可能影响到下一个; 这就是计算机发展中的并发问题; 由于是笔者不是计算机专业毕业的学生, 所以对这些不是很了解, 经查阅资料后,将所得记录如下.
引用国外大神来区分并发与并存的区别的一张图并发是指至少两个Action可以同时存在, 并行至少两个Action可以同时run
并发初了解
在过去单核CPU时代, 碰到并发问题的时候, 处理方式是多个线程不断交替换入换出内存(上图), 给你一种并发已经解决的错觉, 而现代多核CPU时代, 每一个线程都可以占用一个核心(下图), 这个就是并行解决.
实际运用
我们在开发的过程中可能会碰到一个界面多个网络请求的需求情况;
此时要考虑这几个请求之间的关系, 是不是有相互依赖的关系
一. 多个网路请求彼此依赖
方式之一采用GCD
dispatch_group_t
结合信号量dispatch_semaphore_t
(或者采用外部变量bool或者数字来记录)来实现
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
NSLog(@"__1");
dispatch_semaphore_signal(semphore);
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)), queue, ^{
// NSLog(@"1");
// dispatch_semaphore_signal(semphore);
// });
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
NSLog(@"__2");
dispatch_semaphore_signal(semphore);
});
dispatch_group_notify(group, queue, ^{
// dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
});
方式之二采用线程池
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation * bolckOperation = [NSBlockOperation blockOperationWithBlock:^{
for (NSInteger i = 0; i<2; i++) {
NSLog(@"%ld__%@", i, [NSThread currentThread]);
}
}];
NSBlockOperation * blcokA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是AAAA");
}];
// 添加依赖 blcokA需要在bolckOperation操作完成之后才能进行
[blcokA addDependency:bolckOperation];
[queue addOperation:bolckOperation];
[queue addOperation:blcokA];
NSOperationQueue
是apple封装GCD的一个新的管理线程的api, 很简单很强大, 而GCD则是封装C的, 简单的多线程建议使用GCD, 复杂点的使用NSOperationQueue
这里想提一下信号量这个概念dispatch_semaphore_t
跟信号量相关的函数只有三个dispatch_semaphore_create(long value)
, dispatch_semaphore_signal(semphore)
, dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER)/DISPATCH_TIME_NOW
, 其中dispatch_semaphore_wait
与dispatch_semaphore_signal
成对出现, signal是发射信号, 信号量加一; wait是接受信号, 信号量减一.
多个网络请求完成后, 集中更新UI
这里采用的是dispatch_group_t
// 创建信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 创建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
NSLog(@"yue");
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
NSLog(@"duihuan11");
});
dispatch_group_async(group, queue, ^{
dispatch_semaphore_signal(semaphore);
});
dispatch_group_notify(group, queue, ^{
// 三个请求对应三次信号等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//在这里 进行请求后的方法,回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI操作
NSLog(@"value: %@", semaphore);
});
});
在线程池中取消依赖关系, 可以满足需求
代码地址:Demo
PS: 日积月累, 天天进步!
--END--