1.dispatch_async和dispatch_sync的区别
(来自http://www.cnblogs.com/zhidao-chen/p/3598215.html 的总结)
首先,同、异步操作只是在当前线程中,操作的是否按照顺序执行的问题,与线程无必然联系。
主线程中可以有同步,异步操作,子线程里也可以有同步和异步的操作。
只是如果执行异步操作了,说明在当前线程中(可能当前是主线程或一个子线程),必然启动了一个子线程来执行任务,异步操作也叫做“把一个操作放进了一个非主队列的队列中执行”。
dispatch_sync(),同步添加操作(进队列中)。他是等待添加进队列里面的操作完成之后再继续执行。
dispatch_async ,异步添加进任务队列,它不会做任何等待。
dispatch_async(queue,block) async 异步队列,dispatch_async函数会立即返回, block会在后台异步执行。
dispatch_sync(queue,block) sync 同步队列,dispatch_sync函数不会立即返回,即阻塞当前线程,等待 block同步执行完成。
总结:
首先区分异步和同步操作:
dispatch_sync(),同步添加操作。它是等待添加进()里面的操作完成之后再继续执行。
dispatch_async ,异步添加进任务队列,它不会做任何等待,跳过执行之后的代码去。
然后是区分串行队列和并行队列:
串行队列:添加进队列的任务顺序执行
并行队列:添加进队列的任务并行执行,顺序不一定
另外,主队列是特殊的串行队列,全局队列dispatch_get_global_queue是系统自带并发队列,可以直接使用。队列能代表着线程,主队列执行任务就是在主线程里执行任务,非主队列执行任务就是在子队列执行任务。
但注意,只有将dispatch_async(代表异步)搭配非主队列(代表并发)执行任务,才叫做多线程操作。多线程肯定应该是异步并发执行。
注意:异步、队列、线程的关系:http://www.jianshu.com/p/8e81d8caee34
队列中可以添加多个线程,多个线程可以在这串行(hang)队列里一次执行一个线程;或者在并发队列里,一次执行多个线程。
!!!! 通过dispatch_async 使用异步,来将任务添加到队列中,会创建线程来执行任务,从而实现了异步操作,多线程操作。
并行队列 就是多条线程一起 执行任务
1.dispatch_sync:同步添加任务到队列,不会创建新的线程,都是在当前线程中处理的。无论添加到串行队列里或者并行队列里,都是串行效果,因为这个方法是等任务执行完成以后才会返回。
2.dispatch_async:异步添加任务到
2-1:mainQueue不创建线程,在主线程中串行执行
2-2:globalQueue 和 并行队列:根据任务系统决定开辟线程个数
2-3:串行对列:创建一个线程:串行执行。
异步是用来加入到队列中,这样会开辟线程来执行操作。
且无论多少个异步加入到串行队列,都只会开一个线程;有多少个异步加入到并行队列,就会开辟多少个线程。
所以启动多线程里执行的是一个blcok语句块,这样就是在异步执行block里的内容,写法很方便简洁。
2.关于全局队列和并发队列
dispatch_queue_create(nil,DISPATCH_QUEUE_CONCURRENT);是创建了一个并发队列,属于自定义的用户队列
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);也是一个并发队列,属于一个全局的并发队列;
3.GCD Queue 分为三种:
http://www.jianshu.com/p/46500f070e9c
1,The main queue :主队列(主线程的串行队列),主线程就是在个队列中。
2,Global queues : 全局(并发)队列。
3,用户(自定义)队列:是用函数dispatch_queue_create创建的自定义队列。可以创建 并发队列和串行队列。
注意:
并发队列,用于实现队列们之间同时并发地执行。如果你的需求需要某个并发线程先执行,可以通过设置优先级来达到目的,但是因为线程是并发执行的,所以你不能保证哪个线程会先执行完,也就是不能保证我们的耗时任务是按照顺序执行的。
串行队列,用于实现队列间顺序执行。
4.GCDDelay:延迟执行: 需求延迟3秒后,执行某项操作
与NSThread的延迟执行比较:NSThread冗长,但精确度高,且能取消延迟执行操作;GCDDelay代码精简,但有毫秒级误差,没有取消操作。
dispatch_queue_tconcurrentQueue =dispatch_queue_create("my.concurrent.queue",DISPATCH_QUEUE_CONCURRENT);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,NSEC_PER_SEC*2.f), concurrentQueue, ^{
NSLog(@"GCD延迟2秒执行");
});
5.GCDGroup:能够监听 加入到组中的线程的执行情况。从而可以实现一些特殊需要,如既希望多线程间并发执行,又希望其中一个线程在其他线程完成后执行。
使用:
1、创建线程组:dispatch_group_tgroup =dispatch_group_create();
2、创建一个线程队列dispatch_queue_tqueue =dispatch_queue_create("my.concurrent.queue",DISPATCH_QUEUE_CONCURRENT);
3、让队列中的每一个线程,都在group中运行
dispatch_group_async(group, queue, ^{
NSLog(@"1");
});
4、notify监听线程组中 之前的线程是否执行完成,并执行block
dispatch_group_notify(group, queue, ^{
NSLog(@"3");
});
6.GCDTimer:GCD定时器,让一个操作在GCD定时器开启后,在某线程内,每个NSEC_PER_SEC时间执行一次。
//获得队列
dispatch_queue_tqueue =dispatch_get_main_queue();
//创建一个定时器(dispatch_source_t本质还是个OC对象)
dispatch_source_ttimer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, queue);
//设置定时器的各种属性(几时开始任务,每隔多长时间执行一次)
// GCD的时间参数,一般是纳秒NSEC_PER_SEC(1秒== 10的9次方纳秒)
//何时开始执行第一个任务
// dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC)比当前时间晚3秒
dispatch_time_tstart =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0*NSEC_PER_SEC));
uint64_tinterval = (uint64_t)(1.0*NSEC_PER_SEC);
dispatch_source_set_timer(timer, start, interval,0);
//设置回调
dispatch_source_set_event_handler(timer, ^{
NSLog(@"GCD定时器");
});
//启动定时器
dispatch_resume(timer);
7.GCDSemaphore:信号量,能实现让两个异步线程,同步执行。
使用方法:先创建GCDSemaphore,然后在需要先执行的线程中 让发出信号,再在需要后执行的线程中 让信号等待。
//信号量的使用就这3句
// 1.创建信号量
dispatch_semaphore_tdispatchSemaphore =dispatch_semaphore_create(0);
dispatch_queue_tgQueue =dispatch_get_global_queue(0,0);
dispatch_async(gQueue, ^{
NSLog(@"1");
// 2.发送信号量
dispatch_semaphore_signal(dispatchSemaphore);//线程1执行完进行发送信号
});
dispatch_async(gQueue, ^{
// 3.等待信号(发送与等待信号量是配对使用的)
//原理:线程1,2会同时并发的执行,到线程2执行到这里,遇到dispatch_semaphore_wait,会停下来看看是否信号量已发送,发送了才往下执行
dispatch_semaphore_wait(dispatchSemaphore,DISPATCH_TIME_FOREVER);//线程2的内容执行前等待信号
NSLog(@"2");
});