iOS中的GCD(一)

一、GCD有三种类型的Queue.

1、main queue:主线程队列,是一个串行的队列,一般用来刷新UI。

dispatch_async(dispatch_get_main_queue(), ^{
       // 刷新UI
    });

2、gloable queue:全局队列,是一个并行队列

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       // 网络请求
    });

3、自定义队列,有两种:

3.1、serial queue:串行队列

    dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);

3.2、concurrent queue:并行队列

    dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);

二、dispatch_sync和dispatch_async的block中使用串行和并行队列

1、在dipatch_sync中使用串行队列

测试代码

- (void)test_disptch_sync_serial_queue {
    dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_sync(serial_queue, ^{
            NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
        });
    }
    NSLog(@"running on main thread = %@", [NSThread currentThread]);
}

输出结果

2016-10-21 10:39:34.649 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==0
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==1
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==2
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==3
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==4
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==5
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==6
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==7
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==8
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread=={number = 1, name = main}, 
index==9
2016-10-21 10:39:34.677 GCD_Demo[1133:9050010] running on main thread = {number = 1, name = main}

结论:

1、dispatch_sync,并没有创建新的线程,而是直接在当前的线程(这里是主线程)执行。
2、running on main thread在最后执行的。会阻塞当前线程。
3、符合FIFO的原则。
这就是说,在dispatch_sync中执行使用串行队列执行任务时,不会创建新的线程,而是直接在当前的线程执行队列中的任务。

2、在dipatch_sync中使用并行队列

测试代码:

- (void)test_disptch_sync_concurrent_queue {
    dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_sync(concurrent_queue, ^{
            NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
        });
    }
    NSLog(@"running on main thread = %@", [NSThread currentThread]);
}

输出结果:

2016-10-21 10:57:48.055 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==0
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==1
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==2
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==3
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==4
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==5
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==6
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==7
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==8
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread=={number = 1, name = main}, 
index==9
2016-10-21 10:57:48.081 GCD_Demo[1332:9070229] running on main thread = {number = 1, name = main}

结论:

结果和在dispatch_sync中执行串行队列的任务结果一模一样。
为什么?不应该是并行的么,多个线程执行么?
这是因为:dispatch_sync不会创建新的线程的原因。执行并行队列的任务也在同一个线程。

3、dispatch_async中使用串行队列

测试代码:

- (void)test_disptch_async_serial_queue {
    dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_async(serial_queue, ^{
            NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
        });
    }
    NSLog(@"running on main thread = %@", [NSThread currentThread]);
}

输出结果:

2016-10-21 11:21:17.948 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==0
2016-10-21 11:21:17.948 GCD_Demo[1576:9087107] running on main thread = {number = 1, name = main}
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==1
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==2
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==3
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==4
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==5
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==6
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==7
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==8
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread=={number = 4, name = (null)}, 
index==9

结论:

1、在dispatch_async中使用的线程都为同一个线程,因为他们的地址都是0x610000274a00。
2、输出结果符合FIFO。
3、running on main thread 的输出位置是随机的,说明执行是随机的。这个符合我们的预期,因为dispatch_async会创建新的线程去执行队列中的任务,不会阻塞主线程。

4、在dispatch_async中使用并行队列

测试代码:

- (void)test_disptch_async_concurrent_queue {
    dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger i = 0; i < 10; i++) {
        dispatch_async(concurrent_queue, ^{
            NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
        });
    }
    NSLog(@"running on main thread = %@", [NSThread currentThread]);
}

输出结果:

2016-10-21 11:37:31.875 GCD_Demo[1710:9100006] thread=={number = 3, name = (null)}, 
index==0
2016-10-21 11:37:31.876 GCD_Demo[1710:9100028] thread=={number = 11, name = (null)}, 
index==8
2016-10-21 11:37:31.875 GCD_Demo[1710:9100027] thread=={number = 10, name = (null)}, 
index==7
2016-10-21 11:37:31.875 GCD_Demo[1710:9100004] thread=={number = 6, name = (null)}, 
index==3
2016-10-21 11:37:31.875 GCD_Demo[1710:9099961] running on main thread = {number = 1, name = main}
2016-10-21 11:37:31.875 GCD_Demo[1710:9100026] thread=={number = 8, name = (null)}, 
index==6
2016-10-21 11:37:31.875 GCD_Demo[1710:9100024] thread=={number = 7, name = (null)}, 
index==4
2016-10-21 11:37:31.876 GCD_Demo[1710:9100029] thread=={number = 12, name = (null)}, 
index==9
2016-10-21 11:37:31.875 GCD_Demo[1710:9100003] thread=={number = 5, name = (null)}, 
index==2
2016-10-21 11:37:31.875 GCD_Demo[1710:9100020] thread=={number = 4, name = (null)}, 
index==1
2016-10-21 11:37:31.875 GCD_Demo[1710:9100025] thread=={number = 9, name = (null)}, 
index==5

结论:

1、输出结果每次都不同,说明我们的输出结果是并发的,并且是由多个线程同时执行的。
2、每次打印的线程地址不同,说明是并发的。
3、running on main thread位置是随机的,说明不会阻塞主线程。
当然线程的总数量是有限制的,不是会无限制的创建新的线程的。

你可能感兴趣的:(iOS中的GCD(一))