1.主线程队列中实测。
a.主线程队列中不能执行同步,线程阻塞。代码中有异步和同步两个执行操作,当同步执行在前时,线程阻塞,无法走到异步代码。当异步执行在前时,可以走到同步代码,但是此时线程阻塞,异步代码块无法回调,即异步代码大括号里的部分无法执行。
代码:
dispatch_queue_t queue=dispatch_get_main_queue();
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_async(queue, ^{
NSLog(@"async线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程01--\n%@",[NSThreadcurrentThread]);
});
打印:
2017-05-25 15:54:39.278 GCD_TEST[22554:339346] 主线程--
{number = 1, name = main}
b.主队列中异步执行并未开启新线程,且按执行顺序回调。执行过程为:async线程01,async线程02,async线程03,回调async线程01,回调async线程02,回调async线程03。
代码:
dispatch_queue_tqueue=dispatch_get_main_queue();
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_async(queue, ^{
NSLog(@"async线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程03--\n%@",[NSThreadcurrentThread]);
});
打印:
2.自创串行队列中实测。
a.同步操作不会开启新线程,异步操作会开启新线程,但是开启数量应在1到异步操作数量之间。例如我有3个异步操作,打印开启了2个新线程。执行顺序,如异步在前,同步再后:1.执行异步操作,2.执行同步操作,3.执行异步回调,4.执行同步回调。如同步在前异步在后:1.执行同步操作,2,执行同步回调,3,执行异步操作,4,执行异步回调。
代码:
dispatch_queue_tqueue=dispatch_queue_create("自创串行队列",DISPATCH_QUEUE_SERIAL);
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_async(queue, ^{
NSLog(@"async线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程03--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程03--\n%@",[NSThreadcurrentThread]);
});
打印:
b.自创串行队列中异步执行有开启新线程,当队列中只有异步操作时只开启了一条新线程,实测9个异步操作只开启了一条新线程,跟a中的情况有所不同。同样按执行顺序回调。执行过程为:async线程01,async线程02,async线程03...回调async线程01,回调async线程02,回调async线程03...
代码:
dispatch_queue_tqueue=dispatch_queue_create("自创串行队列",DISPATCH_QUEUE_SERIAL);
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_async(queue, ^{
NSLog(@"async线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程03--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程04--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程05--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程06--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程07--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程08--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程09--\n%@",[NSThreadcurrentThread]);
});
打印:
3.全局并行队列实测。
在全局并行队列中,同步操作未开辟新线程,异步操作开辟多个新线程,实测3个异步操作,打印开辟3个新线程。需要注意的是,当同步操作在异步操作之前时,总是在同步操作回调结束后才会执行异步操作。因为,不管是同步操作还是异步操作,在执行之前,都处于同一线程下,都遵循先进先出的原则。我们应该讲一个block看成两个部分,一个就是block对象,第二个就是block大括号里的执行部分。同步操作和异步操作之分在于,同步操作将block对象和其回调部分都以顺序添加在当前线程中,而异步操作则是将block对象添加在当前顺序中,而其回调部分则另开线程去处理。所以,不管是串行队列还是并行队列,只要同步操作在异步操作之前,那就是先执行完同步操作的回调再去执行异步操作。
代码:
dispatch_queue_tqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_sync(queue, ^{
NSLog(@"sync线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程01--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程02--\n%@",[NSThreadcurrentThread]);
});
dispatch_async(queue, ^{
NSLog(@"async线程03--\n%@",[NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"sync线程03--\n%@",[NSThreadcurrentThread]);
});
打印:
其中sync线程01,sync线程02回调总是按顺序在最前面,另外四个操作回调顺序不能确定。
4.串行队列和并行队列差异实测。
串行决定该队列上的任务完成一个再执行下一个,并行决定该队列上的任务不必须等上一个任务完成再执行下一个。
a.串行队列下,同步回调中插入一个同步任务。执行顺序:1.走第一个同步任务,2.走第一个同步的回调任务,3.走插入的同步任务,4.走插入的同步的回调任务(这一步走不下了,线程已经被阻塞,因为2没有走完)。
注:串行队列下异步回调中插入一个同步任务跟a的情况一样,如果插入的是异步任务顺利执行。
代码:
dispatch_queue_tqueue=dispatch_queue_create("自创串行队列",DISPATCH_QUEUE_SERIAL);
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_sync(queue, ^{
NSLog(@"sync线程01--\n%@",[NSThreadcurrentThread]);
dispatch_sync(queue, ^{
NSLog(@"sync线程02--\n%@",[NSThreadcurrentThread]);
});
});
打印:
b.并行队列下,同步回调中插入一个同步任务。执行顺序:1.走第一个同步任务,2.走第一个同步的回调任务,3.走插入的同步任务,4.走插入的同步的回调任务(线程未阻塞,因为并行不需要等2走完)。
注:并行队列下异步回调中插入一个同步任务跟b的情况一样,如果插入的是异步任务顺利执行。
代码:
dispatch_queue_tqueue=dispatch_queue_create("自创并行队列",DISPATCH_QUEUE_CONCURRENT);
NSLog(@"主线程--\n%@",[NSThreadmainThread]);
dispatch_sync(queue, ^{
NSLog(@"sync线程01--\n%@",[NSThreadcurrentThread]);
dispatch_sync(queue, ^{
NSLog(@"sync线程02--\n%@",[NSThreadcurrentThread]);
});
});
打印:
结语:自己动手,把可能遇到的线程组合情况一一试验,就会加深其中的理解。另外自创并行队列和全局并行队列运行效果一致,就不再赘述。