iOS之多线程 2

200 阅读4分钟

GCD

GCD(GRAND CENTRAL DISPATCH),就是牛逼的中枢调度器。C语言写的,提供了多种函数。

1.任务和队列

GCD两个核心的概念就是任务和队列。 任务:执行什么操作的。 队列:专门来存放任务的。 GCD的使用很简单,也就是先把任务定制好,然后放在队列中,GCD会自动的将任务从队列中取出来,然后放到对应的线程中去执行,任务的取出遵循先进先出和后进后出的原则。

2.同步、异步

// 同步   
 dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
// 异步
dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
queue:队列
block:任务

同步和异步的区别: 同步:只能在当前线程中执行任务,不具备开启新的线程的能力 异步:可以在新的线程中执行任务,具备开启新的线程的能力

3.串行队列、并发队列

并发队列:可以将多个任务并发的同时的执行,自动的开启多个线程同时执行任务。 串行队列:任务是一个接着一个的执行。

以上的四个术语的一些说明:关于同步异步,只是说明了有无开具新的线程的能力;而对串行和并发队列来说就是任务执行的方式。

4.GCD的基本使用

  • 异步并发:
/**
 异步+并发->会开启多条线程的,队列中任务是异步执行的
 */
- (void)wjAsyncConcurrent {
    // 1.创建队列
    // DISPATCH_QUEUE_CONCURRENT : 并发队列
    dispatch_queue_t queue = dispatch_queue_create("com.wj.downLoad", DISPATCH_QUEUE_CONCURRENT);
    // 2.定制任务->还将把任务添加到队列中
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 1 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 2 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 3 : %@", [NSThread currentThread]);
    });
    /*
     打印结果
     异步+并发 1 : <NSThread: 0x600000070480>{number = 3, name = (null)}
     异步+并发 3 : <NSThread: 0x600000070840>{number = 4, name = (null)}
     异步+并发 2 : <NSThread: 0x600000070680>{number = 5, name = (null)}
     */
}
  • 异步串行
/**
 异步+串行->会开线程,开了一条线程,队列中的任务是串行执行的。
 */
- (void)wjAsyncSerial {
    dispatch_queue_t queue = dispatch_queue_create("com.wj.download", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"异步+串行 1 : %@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"异步+串行 2 : %@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"异步+串行 3 : %@", [NSThread currentThread]);
    });
    /*
     打印结果
     异步+串行 1 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
     异步+串行 2 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
     异步+串行 3 : <NSThread: 0x60800006dd80>{number = 3, name = (null)}
     */
}
  • 同步并发
/**
 同步+并发->不会开线程,在主线程中执行,且任务是串行执行
 */
- (void)wjSyncConcurrent {
    dispatch_queue_t queue = dispatch_queue_create("com.wj.downLoad", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        NSLog(@"同步+并发 1 : %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步+并发 2 : %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步+并发 3 : %@", [NSThread currentThread]);
    });
    /*
     打印结果
     同步+并发 1 : <NSThread: 0x608000261f80>{number = 1, name = main}
     同步+并发 2 : <NSThread: 0x608000261f80>{number = 1, name = main} 
     同步+并发 3 : <NSThread: 0x608000261f80>{number = 1, name = main}
     */
}
  • 同步串行
/**
 同步+串行->不会开线程
 */
- (void)wjSyncSerial {
    dispatch_queue_t queue = dispatch_queue_create("com.wj.download", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        NSLog(@"同步+串行 1 : %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步+串行 2 : %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步+串行 3 : %@", [NSThread currentThread]);
    });
    /*
     打印结果
     同步+串行 1 : <NSThread: 0x600000077180>{number = 1, name = main}
     同步+串行 2 : <NSThread: 0x600000077180>{number = 1, name = main}
     同步+串行 3 : <NSThread: 0x600000077180>{number = 1, name = main}
     */
}
  • 线程开多少的问题?
/**
 获得全局并发队列
 */
- (void)wjGetGlobleConcurrentQueue {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 1 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 2 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 3 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 4 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 5 : %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步+并发 6 : %@", [NSThread currentThread]);
    });
    /*
     打印结果->可以显示出,并不是有多少个任务就创建多少个线程,而是有系统自己决定的。
     异步+并发 3 : <NSThread: 0x60000026c700>{number = 5, name = (null)}
     异步+并发 4 : <NSThread: 0x6080002688c0>{number = 6, name = (null)}
     异步+并发 1 : <NSThread: 0x608000268c80>{number = 3, name = (null)}
     异步+并发 2 : <NSThread: 0x608000268a80>{number = 4, name = (null)}
     异步+并发 5 : <NSThread: 0x60000026c3c0>{number = 7, name = (null)}
     异步+并发 6 : <NSThread: 0x60000026c700>{number = 5, name = (null)}
     */  
}