1、DISPATCH_QUEUE_SERIAL
1.1、串行队列使队列中的任务同步执行,单次只能执行一个任务
1.2、示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #import "ViewController.h" #import <pthread.h> @implementation ViewController static NSUInteger ticketCount_ = 20; - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t queue = dispatch_queue_create("com.yusian.custom-queue", DISPATCH_QUEUE_SERIAL); for (int i = 0; i < 5; i++) { dispatch_async(queue, ^{ [self saleTicket]; }); } } - (void)saleTicket { NSUInteger remain = ticketCount_; sleep(1); ticketCount_ = --remain; NSLog(@"%ld, %@", ticketCount_, [NSThread currentThread]); } @end |
执行结果:
2018-11-27 21:45:13.668026+0800 MultiThread[1652:65435] 19, <NSThread: 0x60000349d340>{number = 3, name = (null)} 2018-11-27 21:45:14.670487+0800 MultiThread[1652:65435] 18, <NSThread: 0x60000349d340>{number = 3, name = (null)} 2018-11-27 21:45:15.674636+0800 MultiThread[1652:65435] 17, <NSThread: 0x60000349d340>{number = 3, name = (null)} 2018-11-27 21:45:16.678230+0800 MultiThread[1652:65435] 16, <NSThread: 0x60000349d340>{number = 3, name = (null)} 2018-11-27 21:45:17.683553+0800 MultiThread[1652:65435] 15, <NSThread: 0x60000349d340>{number = 3, name = (null)} |
2、dispatch_semaphore
2.1、dispatch_semaphore(dispatch:派遣、调度,semaphore:信号量)
2.2、dispatch_semaphore的作用是限制gcd的最大并发量,如果为1则类似同步效果
2.3、示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #import "ViewController.h" #import <pthread.h> @interface ViewController() { dispatch_semaphore_t _semaphore; } @end @implementation ViewController static NSUInteger ticketCount_ = 20; - (void)viewDidLoad { [super viewDidLoad]; // 如果参数为5则同时执行5条线程,如果为1,则每次只有一条线程 _semaphore = dispatch_semaphore_create(1); for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self saleTicket]; }); } } - (void)saleTicket { // 第二个参数的超时时间,超过超时时间则直接执行,不再等待,DISPATCH_TIME_FOREVER为一直等待 dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); NSUInteger remain = ticketCount_; sleep(1); ticketCount_ = --remain; NSLog(@"%ld", ticketCount_); // 执行结束后发送信号释放线程占用 dispatch_semaphore_signal(_semaphore); } @end |
执行结果:
2018-11-27 21:14:58.762370+0800 MultiThread[1269:34401] 19 2018-11-27 21:14:59.766374+0800 MultiThread[1269:34404] 18 2018-11-27 21:15:00.770787+0800 MultiThread[1269:34402] 17 2018-11-27 21:15:01.771741+0800 MultiThread[1269:34403] 16 2018-11-27 21:15:02.773284+0800 MultiThread[1269:34412] 15 2018-11-27 21:15:03.777777+0800 MultiThread[1269:34416] 14 2018-11-27 21:15:04.782864+0800 MultiThread[1269:34417] 13 2018-11-27 21:15:05.787534+0800 MultiThread[1269:34418] 12 2018-11-27 21:15:06.792096+0800 MultiThread[1269:34419] 11 2018-11-27 21:15:07.794997+0800 MultiThread[1269:34420] 10 |
3、dispatch_group_notify
3.1、如果需要先执行A、B,再执行C,该如何实现;
3.2、先将A、B加入到一个并行队列组dispatch_group;
3.3、C通过dispatch_group_notify等待A、B结束后被唤醒执行
3.4、示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #import "ViewController.h" #import <pthread.h> @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT); dispatch_group_async(group, queue, ^{ [self methodA]; }); dispatch_group_async(group, queue, ^{ [self methodB]; }); // 等待线程结束后被唤醒执行 dispatch_group_notify(group, queue, ^{ [self methodC]; }); } - (void)methodA { NSLog(@"---a---"); } - (void)methodB { NSLog(@"---b---"); sleep(2); } - (void)methodC { NSLog(@"---c---"); } |
执行结果:
2018-11-27 21:51:51.798390+0800 MultiThread[1774:73287] ---a--- 2018-11-27 21:51:51.798393+0800 MultiThread[1774:73288] ---b--- 2018-11-27 21:51:53.803127+0800 MultiThread[1774:73288] ---c--- |