1.GCD信号量:dispatch_semaphore
(1)dispatch_semaphore_create创建一个Semaphore并初始化信号的总量
(2)dispatch_semaphore_signal:发送一个信号,让信号量+1
(3)dispatch_semaphore_waite可使总信号量减1,信号总量小于0时会一直等待(阻塞当前线程),否则就可以正常执行()
示例:北京上海两个窗口售卖火车票
北京火车票开始卖票,信号量为1.走在①处信号量减1,然后继续往下走,此时如果上海火车站也正在卖票,走在①处信号量减1,此时信号总量小于0,开始等待(阻塞当前上海卖票的线程),等到北京卖票完成或者余票为0(北京卖票任务所在线程执行完成)②处,调用 dispatch_semaphore_signal,则此时信号总量为0,继续执行上海卖票任务(上海卖票进程继续执行),执行上海卖票任务完成后信号量加1②处,调用 dispatch_semaphore_signal,信号量恢复为1.
2.GCD队列组:dispatch_group
(1) 创建队列组 dispatch_group_t * group = dispatch_group_create();
(2) 把任务放在队列组 dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//任务一....
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
//任务二....});
(3)执行完前两个异步任务后的两种操作:
① dispatch_group_notify(group,dispatch_get_main_queue(),^{
//任务三
});
当前两个异步任务完成后,把任务三添加到group中。
② dispatch_group_wait (group,DISPATCH_TIME_FOREVER);
此函数会阻塞当前线程,等前两个异步任务完成后才可解除阻塞
3.GCD一次性代码(只执行一次):dispatch_once
/**
* 一次性代码(只执行一次)dispatch_once
*/
- (void)once {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只执行 1 次的代码(这里面默认是线程安全的)
});
}
4.GCD延时执行方法:dispatch_after
dispatch_after 方法并不是在指定时间之后才开始执行处理,而是在指定时间之后将任务追加到主队列中。
5.GCD栅栏方法:dispatch_barrier_async
dispatch_barrier_async 方法会等待前边追加到并发队列中的任务全部执行完毕后,再将指定的任务追加到该barrier异步队列中。等该barrier任务完成后,异步队列才恢复为正常执行后边的任务。
注:dispatch_barrier_async只支持dispatch_queue_create创建的队列,dispatch_get_global_queue无效。
/**
* 栅栏方法 dispatch_barrier_async
*/
- (void)barrier {
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 追加任务 1
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印当前线程
});
dispatch_async(queue, ^{
// 追加任务 2
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印当前线程
});
dispatch_barrier_async(queue, ^{
// 追加任务 barrier
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"barrier---%@",[NSThread currentThread]);// 打印当前线程
});
dispatch_async(queue, ^{
// 追加任务 3
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印当前线程
});
dispatch_async(queue, ^{
// 追加任务 4
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"4---%@",[NSThread currentThread]); // 打印当前线程
});
}