iOS_多线程_GCD

1、GCD串行队列+异步dispatch
说明: 非常非常非常有用的操作
异步,表示会在主线程之外开新的线程,但由于 队列是串行的,故只开 一个(只开一个)新的线程
当dispatch分派好block之后,主线程立即返回,继续向下执行
串行队列,表示:被分派到此队列的block们,将FIFO有序地一个接一个执行
dispatch_async说明:
立即返回,从不等待,队列决定是serially还是concurrently,block_copy(),block_release()


程序运行结果输出:
可以看到:串行队列+异步方式向队列添加block, 只会新开一个线程,所有被添加的block在新开的线程里,愉快而有序地执行
iOS_多线程_GCD_第1张图片

2、GCD串行队列+同步dispatch (极少使用)
同步表示:不会开新线程,就在主线程上运行
串行表示:所有block一个接一个运行
iOS_多线程_GCD_第2张图片
iOS_多线程_GCD_第3张图片
iOS_多线程_GCD_第4张图片

3、并行队列+异步dispatch(容易失控)

开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序

iOS_多线程_GCD_第5张图片
iOS_多线程_GCD_第6张图片
4、并发队列+同步dispatch

关键:因为同步,则不会开新线程,直接使用主线程,

        虽然是并发队列,但由于可有一个执行路线,所以会顺序执行


iOS_多线程_GCD_第7张图片

5、发散思维--->串行队列先同步dispatch十个block,再异步dispatch十个block
既然是同步分派:就是在主线程上执行,完毕后,
再异步分派:开新线程,由于队列是串行,故,只会开一条新线程,一个接一个愉快地执行

iOS_多线程_GCD_第8张图片

6、发散思维--->并行队列中,先同步分派10个block,再异步分派10个blcok
只要是同步dispatch,就只会在主线程上运行
再异步分派,就一定会开新线程,由于是并行队列:故会开N条新线程,N数量不可控制,block们的执行顺序也不可控制
iOS_多线程_GCD_第9张图片


7、发散思维--->并行队列中,先异步分派10个block,再同步分派10个blcok
由于是并行,且是异步dispatch:因此会开启多个线程,并且分派完block后,主线程继续向下执行,
只要是同步的dispatch,只会在主线程上执行,因此N条子线程和主线程 穿插执行
iOS_多线程_GCD_第10张图片
iOS_多线程_GCD_第11张图片

8、系统提供的全局队列,供所有的app使用,与【并行队列】的异同如下:

供所有app使用的全局队列

 全局队列 并行队列的3点区别:

 1、全局队列不需create、只要get就可以得到

 2、全局队列没有名字,因此,调试时,不方便查看

 3、全局队列与并行队列的执行效果完全相同


iOS_多线程_GCD_第12张图片


9、主队列 + 同步dispatch 【 阻塞死
由于主队列  一直在、随时在等待用户的输入,因此主队列,一直在运行,不会退出;
一旦退出,程序就结束了;
因此,在主队列里面 同步分派 一个block,是永远也不会被执行到的,
该block会将主线程 阻塞住,该block后面的代码也永远不会被执行到
iOS_多线程_GCD_第13张图片
10、主队列 + async分派
在主队列中,无论如何dispatch,只要是加入到主队列的block, 统一由主队列进行安排,顺序执行
iOS_多线程_GCD_第14张图片



iOS_多线程_GCD_第15张图片
iOS_多线程_GCD_第16张图片

iOS_多线程_GCD_第17张图片


iOS_多线程_GCD_第18张图片
iOS_多线程_GCD_第19张图片


iOS_多线程_GCD_第20张图片

iOS_多线程_GCD_第21张图片
iOS_多线程_GCD_第22张图片
//
//  ViewController.m
//  GCD
//
//  Created by xss on 14-11-23.
//  Copyright (c) 2014年 beyond. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // [self gcd_serial_async];
    
    // [self gcd_serial_sync];
//    [self gcd_concurrent_async];
//    [self gcd_concurrent_sync];
//    [self gcd_concurrent_sync_async];
//    [self gcd_concurrent_async_sync];
//    [self gcd_serial_sync_async];
//    [self gcd_global_queue];
//    [self gcd_main_queue_sync];
    [self gcd_main_queue_async];
}
/*
 1、主队列 + 异步dispatch (无论如何dispatch,只要加入主队列,都将串行执行,统一由主队列顺序安排)
 */
- (void)gcd_main_queue_async
{
  
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // 快速向 主队列 里面异步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_async(mainQueue, ^{
            NSLog(@"\n---------->异步分派:%@--正在执行 主队列 中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}
/*
 1、主队列 + 同步dispatch  == 永远不被执行
    因为 主队列 一直有一个block 在监听并处理 UI操作,一直阻塞,不会退出,不会完结
    因此,同步dispatch的,排在其后面的block永远不会被执行
 */
- (void)gcd_main_queue_sync
{
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
        NSLog(@"before");
    dispatch_sync(mainQueue, ^{
        NSLog(@"永远也不会被执行到");
    });
        NSLog(@"after");
}
/*
 供所有app使用的全局队列
 全局队列 与 并行队列的一点点区别:
 1、全局队列 不需create、只要get就可以得到
 2、全局队列 没有名字,因此,调试时,不方便查看
 3、全局队列 与并行队列的执行效果完全相同
 */
- (void)gcd_global_queue
{
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 快速向队列里面同步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_sync(globalQueue, ^{
            NSLog(@"\n---------->同步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    // 快速向队列里面异步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_async(globalQueue, ^{
            NSLog(@"\n---------->异步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
}
/*
 并行队列:先异步分派10个,再同步分派10个
 总结:穿插执行
 */
- (void)gcd_concurrent_async_sync
{
    dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    // 快速向队列里面异步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    // 快速向队列里面同步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}
/*
 并行队列:分同步分派10个,再异步分派10个
 */
- (void)gcd_concurrent_sync_async
{
    dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    // 快速向队列里面同步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    // 快速向队列里面异步添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
}
/*
 串行队列:
 1.先sync分派10个block
 2.再async分派10个block
 */
- (void)gcd_serial_sync_async
{
    
    dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
    // 快速向队列里面添加10个block
    for (int i = 0; i<10; i++) {
        // 同步dispatch
        dispatch_sync(queue, ^{
            NSLog(@"---------->同步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    // 快速向队列里面添加10个block
    for (int i = 0; i<10; i++) {
        // 异步dispatch
        dispatch_async(queue, ^{
            NSLog(@"---------->异步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}
/*
 并发队列+同步dispatch
 关键:同步,则不会开新线程,直接使用主线程,
        虽然是并发队列,但由于 可有一个执行路线,所以会顺序执行
 */
- (void)gcd_concurrent_sync
{
    // 参数1:是调试用的,是C字符串,
    // 参数2:A dispatch queue that may invoke blocks concurrently and supports
    // barrier blocks submitted with the dispatch barrier API.
    dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    // 快速向队列里面添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}
/*
 并发队列+异步dispatch
 关键:开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序
 */
- (void)gcd_concurrent_async
{
    // 参数1:是调试用的,是C字符串,
    // 参数2:A dispatch queue that may invoke blocks concurrently and supports
    // barrier blocks submitted with the dispatch barrier API.
    dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    // 快速向队列里面添加10个block
    for (int i = 0; i<10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}
/*
 串行队列 + 同步dispatch   【极少使用】
 既然是 同步dispatch,就没有必要开一条新线程,在主线程上 一个接一个block执行
 */
- (void)gcd_serial_sync
{
    // 参数1:是调试用的,是C字符串,
    // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
    dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
    // 快速向队列里面添加
    for (int i = 0; i<10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}




/*  1、串行队列里面的异步任务
    这个非常有用,举例如下:
    一个串行的队列里,先执行 下载图片的block
    然后再执行滤镜操作(如 红眼、高光、羽化等blcok)
    最后再执行保存block
 */
- (void)gcd_serial_async
{
    // 参数1:是调试用的,是C字符串,
    // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
    dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
    // 快速向队列里面添加
    for (int i = 0; i<10; i++) {
        // Submits a block for asynchronous execution on a dispatch queue.
        // Calls to dispatch_async() always return immediately after the block has
        // been submitted, and never wait for the block to be invoked.
        dispatch_async(queue, ^{
            NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
        });
    }
    
}


@end


串行队列: 同步里面 嵌套了同步,结果是:【永远也不会执行】

因为:理论上 是在主线程 执行完 第一个block,再执行 被添加到queue里面的第2个block,但是:由于 第1个block没执行完,是不会执行 后来添加到queue里面的第2个block,因此阻塞住了,第2个被添加到queue里面的block永远不会被执行
iOS_多线程_GCD_第23张图片


你可能感兴趣的:(ios,并发,gcd,串行)