多线程之GCD##
简介###
全称:Grand Central Dispatch,大中枢调度
优势:GCD是苹果公司为多核的并行运算提出的解决方案
它会自动利用更多的CPU内核,会自动管理线程的生
命周期(创建线程,调度任务,销毁线程),它是纯
C语言,提供了非常多强大的函数。
概念###
任务:执行什么操作
队列:用来存放任务(先进先出,后进后出)
同步:只能在当前线程中执行任务,不具备开启新线程的能力
异步:可以在新的线程中执行任务,具备开启新线程的能力
并发队列:可以让多个任务并发(同时)执行,并发功能只能在异步(dispatch_async)函数下才有效
串行队列:让任务一个一个地执行
基本使用###
1.同步串行队列
//创建同步串行队列并把任务加入队列,没有创建新的子线程,所有任务在主线程上串行执行
//这样写没有啥意义
-(void)createSynSerial
{
// 1.自己创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_SERIAL);
//block中的是任务,将任务加到并行队列中,异步队列会开辟出来新的子线程,任务按添加顺序执行
dispatch_sync(queue, ^{
NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
});
}
2.同步并行队列
//创建同步并行队列并把任务加入队列,不会创建新的线程,都是在当前线程做事情
//这种方式没啥意义
-(void)createSynConcurrent
{
// 1.自己创建一个并行队列 dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT);
//用系统提供的全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//block中的是任务,将任务加到并行队列中,同步队列不会开辟出来新的子线程
dispatch_sync(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
}
});
NSLog(@"------------看看执行顺序--------------");
}
3.异步串行队列
//创建异步串行队列并把任务加入队列,会开启一个新的子线程,任务是串行执行的,完成一个任务,再执行下一个任务
//这种情况只需要把多个任务加入一个block块中即可
-(void)createAsySerial
{
// 1.自己创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_SERIAL);
//block中的是任务,将任务加到并行队列中,异步队列会开辟出来新的子线程,任务按添加顺序执行
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
}
});
NSLog(@"------------看看执行顺序--------------");
}
4.异步并行队列
//创建异步并行队列并把任务加入队列,可以同时开辟多条子线程,并发去执行多个任务
-(void)createAsyConcurrent
{
// 1.自己创建一个并行队列 dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT);
//用系统提供的全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//block中的是任务,将任务加到队列中,异步队列会开辟出来新的子线程
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
}
});
NSLog(@"------------看看执行顺序--------------");
}
5.异步主队列
/**
* 异步函数 + 主队列:只在主线程中执行任务,并没有开辟新的线程
* 很少用没啥意义
*/
- (void)asyncMain
{
// 1.获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.将任务加入队列
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; ++i)
{
NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
}
});
}
6.同步主队列
/**
* 同步函数 + 主队列:会阻塞线程
*/
- (void)syncMain
{
NSLog(@"syncMain ----- begin");
// 1.获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.将任务加入队列
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
NSLog(@"syncMain ----- end");
}
GCD常用函数###
-
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
-(void)gcdBarrierMethod { dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"--------任务1, %@-----------", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"--------任务2, %@-----------", [NSThread currentThread]); }); //等之前任务执行完毕,再执行barrier之后的任务 dispatch_barrier_async(queue, ^{ NSLog(@"--------barrier任务, %@-----------", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"--------任务3, %@-----------", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"--------任务4, %@-----------", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"--------任务5, %@-----------", [NSThread currentThread]); }); }
2.dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);
-(void)gcdAfterMethod
{
NSLog(@"=========%@==========", [NSThread currentThread]);
//3秒之后执行block块中的任务
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"+++++++++%@+++++++++", [NSThread currentThread]);
});
}
3._dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
-(void)gcdOnceMethod
{
static dispatch_once_t onceTocken;
//block中的代码在整个程序运行过程中只会执行一次
dispatch_once(&onceTocken, ^{
NSLog(@"+++++++%@++++++++++", [NSThread currentThread]);
});
}
4.队列组:首先异步执行2个耗时的操作,等执行完毕,再执行第3个操作
5.遍历
6.线程间通信