6个结果搞懂 GCD中 QUEUE 和 async/sync

人盡茶涼 提交于 2019-12-09 17:58:45

同一个blockObject

SSViewController *firstVC = (SSViewController *)self.window.rootViewController;
    [firstVC gcdTestMethod:^{
        for (int i=1; i<5; i++)
        {
            NSString *isMain = [[NSThread currentThread] isMainThread]?@"YES":@"NO";
            NSLog(@"    1 ====% 2d  %@ Main:%@",i,[NSThread currentThread],isMain);
        }
    }];
    [firstVC gcdTestMethod:^{
        for (int i=1; i<5; i++)
        {
            NSString *isMain = [[NSThread currentThread] isMainThread]?@"YES":@"NO";
            NSLog(@"    2 ====% 2d  %@ Main:%@",i,[NSThread currentThread],isMain);
        }
    }];

这里给6个不同实现和不同的结果:

======================== 1 ============================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
    if (!_concurrentQ){
        _concurrentQ =
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
    }
    dispatch_async(_concurrentQ, oneGcdObject);
}


======================== 2 ============================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
    if (!_concurrentQ){
        _concurrentQ =
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
    }
    dispatch_sync(_concurrentQ, oneGcdObject);
}


======================== 3 ============================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
    if (!_concurrentQ){
        _concurrentQ =
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
    }
    dispatch_async(_concurrentQ, oneGcdObject);
}


========================= 4 ===========================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
    if (!_concurrentQ){
        _concurrentQ =
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
    }
    dispatch_sync(_concurrentQ, oneGcdObject);
}


========================= 5 ===========================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
//    if (!_concurrentQ){
        _concurrentQ =
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
//    }
    dispatch_sync(_concurrentQ, oneGcdObject);
}


========================= 6 ===========================
- (void)gcdTestMethod:(gcdBlockObject)oneGcdObject
{
//    if (!_concurrentQ){
        _concurrentQ =
//        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_CONCURRENT);
        dispatch_queue_create(oneQueueName, DISPATCH_QUEUE_SERIAL);
//    }
    dispatch_async(_concurrentQ, oneGcdObject);
}

====================================================

1和2对比: DISPATCH_QUEUE_CONCURRENT 的queue 在使用sync时优先使用主线程(当前线程)
3和4对比: DISPATCH_QUEUE_SERIAL 的queue 无论使用sync还是aync都将遵循FIFO,但使用sync时优先使用主线程(当前线程)
5和6对比: DISPATCH_QUEUE_CONCURRENT 看似创建不同的queue 但由于都是使用sync,实际上都交给了主线程(当前线程),但不是同一个queue;而DISPATCH_QUEUE_SERIAL 看似没有遵循FIFO,实际是完全在两个不同的线程中执行的,这是由于的确创建了两个不同的queue。

Reference about dispatch_sync in "Grand Central Dispatch (GCD) Reference"
"As an optimization, this function invokes the block on the current thread when possible."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!