GCD温故而知新1

作者: 大墙66370 | 来源:发表于2016-11-09 18:36 被阅读65次

GCD 三中queue
1.1 main queue
1.2 global queue
1.3 自己创建 queue
1.3.1 自己创建 queue 分两种
1>串行 dispatch_queue_t serial_queue = dispatch_queue_create("lcc", DISPATCH_QUEUE_SERIAL);
2>并行 dispatch_queue_t serial_concurrent = dispatch_queue_create("lccc", DISPATCH_QUEUE_CONCURRENT);

线程 有两种
2.1 sync 同步
2.2 async 异步

//异步 主队列
-(void)asyncMainQueue{
dispatch_queue_t main_queue = dispatch_get_main_queue();

for (int i = 0; i<5; i++) {
    dispatch_async(main_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"=%@",[NSThread currentThread]);
}
}
2016-11-07 13:39:55.601 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.602 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.603 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.603 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.604 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.611 gcd[5411:330259] i = 0
2016-11-07 13:39:55.611 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.612 gcd[5411:330259] i = 1
2016-11-07 13:39:55.612 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.612 gcd[5411:330259] i = 2
2016-11-07 13:39:55.613 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.613 gcd[5411:330259] i = 3
2016-11-07 13:39:55.613 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.614 gcd[5411:330259] i = 4
2016-11-07 13:39:55.726 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}

异步主队列 分析
异步是不阻塞我们的当前线程(主线程) 所以下面for循环的 NSLog(@"=%@",[NSThread currentThread]);先被打印.async和main_queue组合没有创建新的线程 还是在当前线程中(主线程)这个时候当前线程(主线程)有下面的for循环打印任务 所以要等下面的任务打印好 上面的for循环 才会打印

// 异步 全局队列
-(void)asyncGlobleQueue{
dispatch_queue_t globle_queue = dispatch_get_global_queue(0, 0);

for (int i = 0; i<5; i++) {
    dispatch_async(globle_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}
}
2016-11-07 13:52:18.783 gcd[5479:341111] i = 4
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.783 gcd[5479:341092] i = 1
2016-11-07 13:52:18.783 gcd[5479:341094] i = 3
2016-11-07 13:52:18.783 gcd[5479:341091] i = 2
2016-11-07 13:52:18.783 gcd[5479:341109] i = 0
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.783 gcd[5479:341111] current thread = <NSThread: 0x60800006aac0>{number = 3, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341094] current thread = <NSThread: 0x60800006b500>{number = 5, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341092] current thread =  <NSThread: 0x600000071b00>{number = 4, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341091] current thread = <NSThread: 0x600000071980>{number = 6, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.784 gcd[5479:341109] current thread = <NSThread: 0x6000000719c0>{number = 7, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.793 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}

异步 全局队列分析
首先 异步 没有阻塞当前线程(主线程) 所以打印的第二行 就已经打印了我们下面的for循环了根据打印的log可以清楚的看到 async和globle_queue创建了新的线程 解释一下打印的顺序打印第一行
2016-11-07 13:52:18.783 gcd[5479:341111] i = 4 这个时候创建了新的线程(非主线程)是在新的线程中打印的,不阻塞当前线程(主线程)
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}就是在当前线程打印的上面开辟了一个新线程做他自己的事下面 当前线程 做自己的事 想象一下就是第一个for循环一下就走完了没循环一次(就可能)创建一个线程就结束循环了打印就是在这创建的各个线程中异步打印..所以上面 for循环的顺序和下面的就乱了

//异步 穿行队列
-(void)asyncSerialQueue{
dispatch_queue_t serial_queue = dispatch_queue_create("com.rea", DISPATCH_QUEUE_SERIAL);

for (int i = 0; i<10; i++) {
    dispatch_async(serial_queue, ^{
        NSLog(@"---i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}

for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}
}

2016-11-07 14:19:17.060 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.060 gcd[5549:360461] ---i = 0
2016-11-07 14:19:17.061 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.061 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 1
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 2
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 3
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.063 gcd[5549:360461] ---i = 4
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 5
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 6
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 7
2016-11-07 14:19:17.079 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.079 gcd[5549:360461] ---i = 8
2016-11-07 14:19:17.079 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.079 gcd[5549:360461] ---i = 9
2016-11-07 14:19:17.080 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}

异步 穿行队列分析
异步 不会阻塞当前线程 所以第一行打印的是下面的for循环
2016-11-07 14:19:17.060 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
async 和serial_queue组合会创建新的线程 但是只会创建一个线程 各个线程做各个的事情 打印就是各打印各的. 异步 穿行只会创建一个线程 在这个所以这个 异步串行是 有顺序的额

// 异步 并行
-(void)asyncConcurrentQueue{
dispatch_queue_t concurrent_queue = dispatch_queue_create("lccc", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i<10; i++) {
    dispatch_async(concurrent_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}}

2016-11-07 14:30:55.875 gcd[5596:370161] i = 2
2016-11-07 14:30:55.875 gcd[5596:370159] i = 1
2016-11-07 14:30:55.875 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.875 gcd[5596:370174] i = 0
2016-11-07 14:30:55.876 gcd[5596:370177] i = 5
2016-11-07 14:30:55.876 gcd[5596:370176] i = 4
2016-11-07 14:30:55.875 gcd[5596:370158] i = 3
2016-11-07 14:30:55.876 gcd[5596:370159] current thread = <NSThread: 0x608000263300>{number = 4, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.876 gcd[5596:370178] i = 6
2016-11-07 14:30:55.876 gcd[5596:370161] current thread = <NSThread: 0x60000007abc0>{number = 3, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370177] current thread = <NSThread: 0x608000263240>{number = 6, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370174] current thread = <NSThread: 0x60000007a3c0>{number = 5, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370179] i = 7
2016-11-07 14:30:55.877 gcd[5596:370158] current thread = <NSThread: 0x608000263380>{number = 8, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.877 gcd[5596:370180] i = 8
2016-11-07 14:30:55.877 gcd[5596:370159] i = 9
2016-11-07 14:30:55.877 gcd[5596:370176] current thread = <NSThread: 0x608000263280>{number = 7, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370178] current thread = <NSThread: 0x608000263140>{number = 9, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370179] current thread = <NSThread: 0x60000007ae80>{number = 10, name = (null)}
2016-11-07 14:30:55.884 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.884 gcd[5596:370180] current thread = <NSThread: 0x6080002631c0>{number = 11, name = (null)}
2016-11-07 14:30:55.884 gcd[5596:370159] current thread = <NSThread: 0x608000263300>{number = 4, name = (null)}
2016-11-07 14:30:55.885 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}

异步 并行队列分析
貌似和异步 globle队列是一样的....

====================================================================================================
异步的说完了 现在说一下同步
1 同步 mainQueue
2同步 globleQueue
3同步 serialQueue
3同步 concurrentQueue
第一种 我会在下一篇 单独讨论 下面三种简单说一下如图下图


EE9372F8-FA11-490B-A269-DB9481BE1BB6.png

同步的意思是 (不创建线程) 重点哦 当前在神马线程那么block代码块里面就会在 神马线程 并且同步会立马回调 重点哦立马回调
所以 如图所示 for循环所在的线程 是主线程 那么block里面肯定 也是 主线程 下面for 循环也是 主线程 记住同步 会立马回调 并且block里和 下面的for循环 都是zai 一个线程 在任何(一个)线程中做任务 那么都是 有先后顺序的. 所以fou循环 运行的如图 164 行就会 立马回调 打印block里面的 知道fou循环 结束 再 打印下面for循环的 ...

打印效果是这样的


A7F3A549-FAC5-403C-BBCE-45A5BEE83EF7.png

希望我说明白了

相关文章

  • GCD温故而知新1

    GCD 三中queue1.1 main queue1.2 global queue1.3 自己创建 queue1....

  • 多线程之GCD

    GCD介绍 1、GCD简介 2、GCD任务和队列 3、GCD 的基本使用 4、GCD 线程间的通信 5、GCD 的...

  • GCD温故而知新2

    上篇我们留了一个问题就是 同步主队列为啥会崩这里我们来解释一下 首先看这个上面这个图 这个方法是在viewDidL...

  • iOS面试--GCD常见用法

    项目中常见的GCD用法有已下几种: 1.GCD栅栏函数2.GCD快速迭代(遍历)3.GCD队列组的使用 1.GCD...

  • GCD回顾温习总结(Swift版本)

    1. GCD 简介 什么是 GCD 呢? Grand Central Dispatch(GCD) 是 Apple ...

  • iOS 多线程--GCD

    一、GCD基本介绍 1.GCD简介 GCD是Grand Central Dispatch的缩写,GCD是苹果推出的...

  • 自用算法模板(JAVA版)

    一、数论 1)GCD GCD(求最大公约数) QGCD(快速GCD) extGCD(拓展GCD,解决ax + by...

  • 浅析GCD

    GCD目录: 1. GCD简介 为什么要用GCD呢? GCD可用于多核的并行运算GCD会自动利用更多的CPU内核(...

  • iOS 多线程学习-思维导图版本

    GCD、NSOperation、NSThread 1.GCD 参考地址:iOS 多线程:『GCD』详尽总结 重要概...

  • 7.多线程基础(七)GCD加强

    1.GCD串行队列和并发队列 2.GCD延时执行 3.GCD线程组:(的作用) 4.GCD定时器: GCD的实现 ...

网友评论

    本文标题:GCD温故而知新1

    本文链接:https://www.haomeiwen.com/subject/uxlouttx.html