队列 & 线程的执行方式(任务)
任务:block,消息等函数块,他是由线程执行的。
线程执行任务的方式:
同步线程:当前线程a只能执行完事件A才能执行任务B。
异步线程:当前线程a执行A的时候又开了个线程b,执行任务B
队列:存储任务
串行队列:一个任务(block)接着一个任务的出队。通常由一个线程处理这一个队列
并发队列:一次有多个任务出队,由多个线程处理。使用异步线程执行。
并发
2.GCD:
线程执行方式:
同步:dispatch_sync
异步:dispatch_async
队列:
串行:串行队列,dispatch_queue_create,主队列dispatch_get_main_queue
并发:全局队列,dispatch_get_global_queue异步
mainThread <--->mainQueue
async
3.GCD线程间通讯图:
函数
4.url
dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"download:%@", [NSThread currentThread]); NSURL *url = [NSURL URLWithString:@"http://pic.nipic.com/2007-12-06/2007126205543511_2.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; NSLog(@"image:%@", image); //通知主线程更新 UI dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"updateUI:%@", [NSThread currentThread]); self.imgView.image = image; }); });
outputspa
2016-03-03 12:40:00.368 gcdThread[8835:87857] download:<NSThread: 0x7fa57b532800>{number = 2, name = (null)} 2016-03-03 12:40:00.952 gcdThread[8835:87857] image:<UIImage: 0x7fa57d80d0c0>, {1024, 375} 2016-03-03 12:40:00.952 gcdThread[8835:87600] updateUI:<NSThread: 0x7fa57b605170>{number = 1, name = main}
5.GCD 队列组
串行队列中,任务执行时一个接着一个的。任务间通讯是线性的。B任务能够等待A任务完成后拿到A任务的数据。
在并行队列中,任务执行时异步的。须要靠通知(线程间提早作好约定,当这个约定实现了,才会传递数据)。dispatch_group 组操做做为任务之间通讯的一种约定
.net
- (void) groupMultiDownload { __block UIImage *img1, *img2; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_group_async(group, queue, ^{ NSURL *url1 = [NSURL URLWithString:@"http://pic8.nipic.com/20100731/2531170_101711635627_2.jpg"]; NSData *data1 = [NSData dataWithContentsOfURL:url1]; NSLog(@"download1:%@", [NSThread currentThread]); img1 = [UIImage imageWithData:data1]; }); dispatch_group_async(group, queue, ^{ NSURL *url2 = [NSURL URLWithString:@"http://pic9.nipic.com/20100813/2531170_083235193107_2.jpg"]; NSLog(@"download2:%@", [NSThread currentThread]); NSData *data2 = [NSData dataWithContentsOfURL:url2]; img2 = [UIImage imageWithData:data2]; }); //队列组中全部任务完成后 执行 notify dispatch_group_notify(group, queue, ^{ NSLog(@"download finish:%@", [NSThread currentThread]); UIGraphicsBeginImageContextWithOptions(img1.size, NO, 0.0); [img1 drawInRect:CGRectMake(0, 0, img1.size.width, img1.size.height)]; [img2 drawInRect:CGRectMake(0, 0, img2.size.width, img2.size.height)]; UIImage *fullImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); dispatch_async(dispatch_get_main_queue(), ^{ _imgView.image = fullImg; }); }); }
6.延迟执行线程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{ NSLog(@"------task------%@", [NSThread currentThread]); });//使用的是 全局并发队列,因此会自动开启一个子线程,执行block中的内容
7.代码一次执行:代码在程序运行阶段只会被执行一次code
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"----once"); HMImageDownloader *downloader = [[HMImageDownloader alloc] init]; [downloader download]; });
PS:使用 gcd实现单例模式。
blog