iOS里的多线程杂谈

前言

之前文章就粗略的设计到了多线程,比如说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]);
iOS里的多线程杂谈_第1张图片
GCD2.png

线程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]);
iOS里的多线程杂谈_第2张图片
多线程3.png

很直观的可以看到主线程和线程4是主线程里顺序执行的,线程1,线程3,线程2是在新的线程里,任务串行执行。

总结

最最重要的一点,gcd是对队列的操作,而不是对线程的操作。
可以很明显的看到,在dispatch_sync里使用dispatch_async,会开辟新的线程。dispatch_sync会阻塞当前线程,把代码块里的任务放入到队列的最后,当代码块里的任务执行完后,再去执行下一步的任务。而dispatch_async是用来分派队列的,他不会让代码块马上运行,直接返回,并且把代码块放入到队列的末尾。更直观的,让我们分开来看看吧。
而在dispatch_async里使用dispatch_syncdispatch_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]);

iOS里的多线程杂谈_第3张图片
GCD4.png

发现了么,因为线程2345会在线程6之后执行,只是必然的,知道为什么嘛?如果看懂这篇文章 你就明白了~ ( __) 嘻嘻……

你可能感兴趣的:(iOS里的多线程杂谈)