前言
之前文章就粗略的设计到了多线程,比如说gcd
。其实关于多线程的呢还有NSThread
,NSOperation
。当然,夏夏并不是很了解这两个,唯一有点了解的就是gcd
了,因为它够逼格!
线程和队列
正如我们所知的,gcd
是基于C语言的一种对队列操作的方法。队列有两种,一种是并发队列,一种是串行队列(高中物理知识,并联电路和串联电路)。但是呢,一开始认识gcd
的时候都说他是一种多线程的编程,why?
是的呢,首先线程是有同步执行和异步执行的区别的。同步就是说你的任务在当前线程中执行。异步呢,就是你的任务是在另外一条线程中执行的。而gcd
的队列,可分为两种队列:并发队列和串行队列。
(1)并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效。
(2)串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
补充说明
有4个术语比较容易混淆:同步、异步、并发、串行
同步和异步决定了要不要开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力
并发和串行决定了任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
又到了一言不合上代码的时候了。
dispatch_sync里的dispatch_async
NSLog(@"主线程----%@", [NSThread mainThread]);
dispatch_queue_t queue = dispatch_queue_create("SLP", NULL);
dispatch_queue_t newQueue = dispatch_queue_create("SHEN", NULL);
dispatch_queue_t newQueue2 = dispatch_queue_create("Xia", NULL);
dispatch_sync(queue, ^{
NSLog(@"当前线程1-----%@", [NSThread currentThread]);
dispatch_async(newQueue, ^{
sleep(3);
NSLog(@"当前线程3-----%@", [NSThread currentThread]);
});
sleep(2);
dispatch_async(newQueue2, ^{
sleep(2);
NSLog(@"当前线程2-----%@", [NSThread currentThread]);
});
});
NSLog(@"当前线程4-----%@", [NSThread currentThread]);
线程1和线程4是按照顺序执行下来的,线程4等待了2秒之后才执行。然而线程2和线程3是并发执行,开启了新的线程,显示结果就是 按照执行速度(线程sleep的时间)的快慢和执行开始的时间。
dispatch_async里的dispatch_sync
NSLog(@"主线程----%@", [NSThread mainThread]);
dispatch_queue_t queue = dispatch_queue_create("SLP", NULL);
dispatch_queue_t newQueue = dispatch_queue_create("SHEN", NULL);
dispatch_queue_t newQueue2 = dispatch_queue_create("Xia", NULL);
dispatch_async(queue, ^{
NSLog(@"当前线程1-----%@", [NSThread currentThread]);
dispatch_sync(newQueue, ^{
sleep(3);
NSLog(@"当前线程3-----%@", [NSThread currentThread]);
});
sleep(2);
dispatch_sync(newQueue2, ^{
sleep(2);
NSLog(@"当前线程2-----%@", [NSThread currentThread]);
});
});
NSLog(@"当前线程4-----%@", [NSThread currentThread]);
很直观的可以看到主线程和线程4是主线程里顺序执行的,线程1,线程3,线程2是在新的线程里,任务串行执行。
总结
最最重要的一点,gcd
是对队列的操作,而不是对线程的操作。
可以很明显的看到,在dispatch_sync
里使用dispatch_async
,会开辟新的线程。dispatch_sync
会阻塞当前线程,把代码块里的任务放入到队列的最后,当代码块里的任务执行完后,再去执行下一步的任务。而dispatch_async
是用来分派队列的,他不会让代码块马上运行,直接返回,并且把代码块放入到队列的末尾。更直观的,让我们分开来看看吧。
而在dispatch_async
里使用dispatch_sync
,dispatch_async
开辟一个新的线程里,dispatch_sync
创建了多个队列,但是队列是串行执行的。
NSLog(@"主线程----%@", [NSThread mainThread]);
dispatch_queue_t queue = dispatch_queue_create("SLP", NULL);
dispatch_queue_t newQueue = dispatch_queue_create("SHEN", NULL);
dispatch_queue_t newQueue2 = dispatch_queue_create("Xia", NULL);
dispatch_async(queue, ^{
NSLog(@"当前线程1-----%@", [NSThread currentThread]);
dispatch_sync(newQueue, ^{
NSLog(@"当前线程2-----%@", [NSThread currentThread]);
dispatch_async(newQueue2, ^{
sleep(3);
NSLog(@"当前线程3-----%@", [NSThread currentThread]);
});
dispatch_async(newQueue2, ^{
sleep(3);
NSLog(@"当前线程4-----%@", [NSThread currentThread]);
});
NSLog(@"当前线程5-----%@", [NSThread currentThread]);
});
});
dispatch_sync(newQueue, ^{
sleep(3);
NSLog(@"当前线程6-----%@", [NSThread currentThread]);
});
NSLog(@"当前线程7-----%@", [NSThread currentThread]);
发现了么,因为线程2345会在线程6之后执行,只是必然的,知道为什么嘛?如果看懂这篇文章 你就明白了~ ( __) 嘻嘻……