GCD-同步、异步、串行、并行的组合执行情况

2018-05-26  本文已影响30人  一双鱼jn

同步操作在各队列下的情况

dispatch_sync(queue,block)

同步 + 主队列 = 死锁

- (void)viewDidLoad {
    [super viewDidLoad];

    dispatch_sync(dispatch_get_main_queue(), ^{
        // do something
    });
}
同步主队列

同步 + 串行队列

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        // do somethings
    });
}

执行到这里,主线程将该任务提交到串行队列中

由于是同步方法,所以主线程会等待这个任务执行完毕再向下执行。

并且因为是同步方法,所以这个任务不会开新的线程来执行,还是由原来的线程执行。

也就是说主线程等这个串行队列中前面的任务执行完毕之后,执行这个任务。执行了这个任务之后向下继续执行。

这种操作没有太大的必要。

图示

同步串行队列

同步 + 并发队列

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        // do somethings
    });
}

相比于同步串行队列,该任务等待时间会短一点,因为是并发队列,前面的任务会被其他线程去执行。其他的基本相同

图示

同步并发队列执行

异步操作在各队列下的情况

dispatch_async(queue,block)

异步 + 主队列

- (void)viewDidLoad {
    [super viewDidLoad];

    dispatch_async(dispatch_get_main_queue(), ^{
        // do something
    });
}

将任务添加到主队列的最后。

图示

异步主队列执行图

异步 + 串行队列

将任务提交到指定的串行队列。

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        // do something
    });
}

因为是异步的,所以主线程将任务提交到这个串行队列之后就可以继续执行。不会卡住主线程。

同样因为是异步的,所以会开启一条子线程来执行这个串行队列中的任务。

因为是串行队列,所以只有一条线程来执行这个队列中的任务。那么该任务就得等前面的任务被该线程执行完了才能被执行。

图示

异步串行队列图示

异步 + 并发队列

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // do something
    });
}

将任务提交到并发队列,因为是异步的,所以不会阻塞主线程,主线程将任务提交到队列之后继续从向下执行。

因为是在并发队列,所以该任务不用等前面的任务完成之后再执行,只要前面的任务被线程开始执行了,接下来就会将该任务分配给一条线程去执行。

异步并行队列图示
上一篇下一篇

猜你喜欢

热点阅读