在tableView列表中,当列表内 Cell 过多,每个cell里面有个网络图片,网络图片自己去GCD Global 创建子线程去下载,然后在主线程里面显示,在快速滑动的时候就会出现这个问题。,偶尔会遇到这种问题:
image.png-
大量的任务提交到后台队列时,某些任务会因为某些原因被锁住导致线程休眠,或者被阻塞,concurrent queue 随后会创建新的线程来执行其他任务。
-
当这种情况变多时,或者 App 中使用了大量 concurrent queue 来执行较多任务时,App 在同一时刻就会存在几十个线程同时运行、创建、销毁。
-
再例如,下面会造成卡顿甚至界面冻屏
- (void)dispatchTest {
for (NSInteger i = 0; i< 10000 ; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self dispatchTask:i];
});
}
}
- (void)dispatchTask:(NSInteger)index {
//模拟耗时操作,比如DB,网络,文件读写等等
sleep(10);
NSLog(@"----:%ld", index);
}
-
CPU 是用时间片轮转来实现线程并发的,尽管 concurrent queue 能控制线程的优先级,但当大量线程同时创建运行销毁时,这些操作仍然会挤占掉主线程的 CPU 资源。
-
dispatch_async 函数分发到全局队列不一定会新建线程执行任务,全局队列底层有一个的线程池,如果线程池满了,那么后续的任务会被 block 住,等待前面的任务执行完成,才会继续执行。如果线程池中的线程长时间不结束,后续堆积的任务会越来越多,此时就会存在 APP crash的风险。
-
全局队列的底层是一个线程池,向全局队列中提交的 block,都会被放到这个线程池中执行,如果线程池已满,后续再提交 block 就不会再重新创建线程。
网友评论