多线程技术GCD的8种队列请求示例

1、串行队列同步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma mark 1、串行队列同步请求
- (void)gcd1
{
    // 创建一个串行队列dispatch_queue_create(标识, 串行队列),DISPATCH_QUEUE_SERIAL 表示串行队列
    dispatch_queue_t queue = dispatch_queue_create("gcd1", DISPATCH_QUEUE_SERIAL);
 
 
    // 发起一个同步任务并执行10次:dispatch_sync(dispatch_queue_t queue, ^{ code })是同步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_sync(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:串行任务按顺序执行,同步任务按顺序执行,无并发数,当前只有一个线程,因此在线程1按顺序执行
}

运行结果:
2014-11-08 15:12:37.952 Test[3166:607] 第 0 次 – {name = (null), num = 1}
2014-11-08 15:12:37.955 Test[3166:607] 第 1 次 – {name = (null), num = 1}
2014-11-08 15:12:37.957 Test[3166:607] 第 2 次 – {name = (null), num = 1}
2014-11-08 15:12:37.958 Test[3166:607] 第 3 次 – {name = (null), num = 1}
2014-11-08 15:12:37.959 Test[3166:607] 第 4 次 – {name = (null), num = 1}
2014-11-08 15:12:37.959 Test[3166:607] 第 5 次 – {name = (null), num = 1}
2014-11-08 15:12:37.960 Test[3166:607] 第 6 次 – {name = (null), num = 1}
2014-11-08 15:12:37.961 Test[3166:607] 第 7 次 – {name = (null), num = 1}
2014-11-08 15:12:37.965 Test[3166:607] 第 8 次 – {name = (null), num = 1}
2014-11-08 15:12:37.966 Test[3166:607] 第 9 次 – {name = (null), num = 1}

2、串行队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma mark 2、串行队列异步请求
- (void)gcd2
{
    // 创建一个串行队列dispatch_queue_create(标识, 串行队列),DISPATCH_QUEUE_SERIAL 表示串行队列
    dispatch_queue_t queue = dispatch_queue_create("gcd2", DISPATCH_QUEUE_SERIAL);
 
    // 发起一个异步任务并执行10次:dispatch_async(dispatch_queue_t queue, ^{ code })是异步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_async(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:异步任务可多个同时进行,无先后顺序,且另开线程并发进行,但由于是串行队列,只能在单个线程中完成,因此在线程2按顺序执行
}

运行结果:
2014-11-08 15:14:35.006 Test[3207:1303] 第 0 次 – {name = (null), num = 2}
2014-11-08 15:14:35.008 Test[3207:1303] 第 1 次 – {name = (null), num = 2}
2014-11-08 15:14:35.011 Test[3207:1303] 第 2 次 – {name = (null), num = 2}
2014-11-08 15:14:35.012 Test[3207:1303] 第 3 次 – {name = (null), num = 2}
2014-11-08 15:14:35.023 Test[3207:1303] 第 4 次 – {name = (null), num = 2}
2014-11-08 15:14:35.024 Test[3207:1303] 第 5 次 – {name = (null), num = 2}
2014-11-08 15:14:35.025 Test[3207:1303] 第 6 次 – {name = (null), num = 2}
2014-11-08 15:14:35.026 Test[3207:1303] 第 7 次 – {name = (null), num = 2}
2014-11-08 15:14:35.028 Test[3207:1303] 第 8 次 – {name = (null), num = 2}
2014-11-08 15:14:35.032 Test[3207:1303] 第 9 次 – {name = (null), num = 2}

3、并行队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma mark 3、并行队列同步请求
- (void)gcd3
{
    // 创建一个并行队列dispatch_queue_create(标识, 串行队列),DISPATCH_QUEUE_CONCURRENT 表示并行队列
    dispatch_queue_t queue = dispatch_queue_create("gcd3", DISPATCH_QUEUE_CONCURRENT);
 
    // 发起一个同步任务并执行10次:dispatch_sync(dispatch_queue_t queue, ^{ code })是同步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_sync(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:由于同步任务,因此只能按顺序执行,由于是并行队列,原则上可创建多个线程,但同步任务让其无法发挥作用
}

运行结果:
2014-11-08 15:15:47.285 Test[3241:607] 第 0 次 – {name = (null), num = 1}
2014-11-08 15:15:47.287 Test[3241:607] 第 1 次 – {name = (null), num = 1}
2014-11-08 15:15:47.288 Test[3241:607] 第 2 次 – {name = (null), num = 1}
2014-11-08 15:15:47.289 Test[3241:607] 第 3 次 – {name = (null), num = 1}
2014-11-08 15:15:47.290 Test[3241:607] 第 4 次 – {name = (null), num = 1}
2014-11-08 15:15:47.292 Test[3241:607] 第 5 次 – {name = (null), num = 1}
2014-11-08 15:15:47.292 Test[3241:607] 第 6 次 – {name = (null), num = 1}
2014-11-08 15:15:47.293 Test[3241:607] 第 7 次 – {name = (null), num = 1}
2014-11-08 15:15:47.294 Test[3241:607] 第 8 次 – {name = (null), num = 1}
2014-11-08 15:15:47.295 Test[3241:607] 第 9 次 – {name = (null), num = 1}

4、并行队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma mark 4、并行队列异步请求
- (void)gcd4
{
    // 创建一个并行队列dispatch_queue_create(标识, 串行队列),DISPATCH_QUEUE_CONCURRENT 表示并行队列
     dispatch_queue_t queue = dispatch_queue_create("gcd4", DISPATCH_QUEUE_CONCURRENT);
 
    // 发起一个异步任务并执行10次:dispatch_async(dispatch_queue_t queue, ^{ code })是异步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_async(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:由于是异步队列,for循环中没等单次循环结束直接新开线程进入下一次循环,因此线程数以及在哪个线程中完成随机,程序员不可控
}

运行结果:
2014-11-08 15:17:04.004 Test[3273:3b03] 第 9 次 – {name = (null), num = 11}
2014-11-08 15:17:04.001 Test[3273:3703] 第 5 次 – {name = (null), num = 7}
2014-11-08 15:17:04.001 Test[3273:3107] 第 1 次 – {name = (null), num = 6}
2014-11-08 15:17:04.002 Test[3273:3603] 第 4 次 – {name = (null), num = 5}
2014-11-08 15:17:04.002 Test[3273:3803] 第 6 次 – {name = (null), num = 8}
2014-11-08 15:17:04.001 Test[3273:3403] 第 2 次 – {name = (null), num = 3}
2014-11-08 15:17:04.003 Test[3273:3a03] 第 8 次 – {name = (null), num = 10}
2014-11-08 15:17:04.006 Test[3273:3503] 第 3 次 – {name = (null), num = 4}
2014-11-08 15:17:04.001 Test[3273:1303] 第 0 次 – {name = (null), num = 2}
2014-11-08 15:17:04.002 Test[3273:3903] 第 7 次 – {name = (null), num = 9}

5、全局队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma mark 5、全局队列同步请求
- (void)gcd5
{
    // 获取全局队列 dispatch_get_global_queue(队列优先级, 预留标记)
    // 有4种优先级,DISPATCH_QUEUE_PRIORITY_DEFAULT为默认优先级,预留标记永远为0,当前无具体含义
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
    // 发起一个同步任务并执行10次:dispatch_sync(dispatch_queue_t queue, ^{ code })是同步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_sync(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:全局队列与自定义队列类似,不同的是全局队列默认是并发队列,但同步请求使其只能单线程执行
}

运行结果:
2014-11-08 15:18:18.991 Test[3310:607] 第 0 次 – {name = (null), num = 1}
2014-11-08 15:18:18.993 Test[3310:607] 第 1 次 – {name = (null), num = 1}
2014-11-08 15:18:18.994 Test[3310:607] 第 2 次 – {name = (null), num = 1}
2014-11-08 15:18:18.994 Test[3310:607] 第 3 次 – {name = (null), num = 1}
2014-11-08 15:18:18.994 Test[3310:607] 第 4 次 – {name = (null), num = 1}
2014-11-08 15:18:18.995 Test[3310:607] 第 5 次 – {name = (null), num = 1}
2014-11-08 15:18:18.995 Test[3310:607] 第 6 次 – {name = (null), num = 1}
2014-11-08 15:18:18.996 Test[3310:607] 第 7 次 – {name = (null), num = 1}
2014-11-08 15:18:18.996 Test[3310:607] 第 8 次 – {name = (null), num = 1}
2014-11-08 15:18:18.997 Test[3310:607] 第 9 次 – {name = (null), num = 1}

6、全局队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma mark 6、全局队列异步请求
- (void)gcd6
{
    // 获取全局队列 dispatch_get_global_queue(队列优先级, 预留标记)
    // 有4种优先级,DISPATCH_QUEUE_PRIORITY_DEFAULT为默认优先级,预留标记永远为0,当前无具体含义
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
    // 发起一个异步任务并执行10次:dispatch_async(dispatch_queue_t queue, ^{ code })是异步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_async(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:全局队列异步请求与并行队列异步请求类似,说明全局队列是并行队列。
}

运行结果:
2014-11-08 15:19:30.332 Test[3337:3503] 第 3 次 – {name = (null), num = 5}
2014-11-08 15:19:30.332 Test[3337:1303] 第 0 次 – {name = (null), num = 2}
2014-11-08 15:19:30.332 Test[3337:3803] 第 6 次 – {name = (null), num = 8}
2014-11-08 15:19:30.332 Test[3337:3107] 第 1 次 – {name = (null), num = 3}
2014-11-08 15:19:30.332 Test[3337:3403] 第 2 次 – {name = (null), num = 4}
2014-11-08 15:19:30.332 Test[3337:3703] 第 5 次 – {name = (null), num = 7}
2014-11-08 15:19:30.332 Test[3337:3603] 第 4 次 – {name = (null), num = 6}
2014-11-08 15:19:30.334 Test[3337:3903] 第 7 次 – {name = (null), num = 9}
2014-11-08 15:19:30.334 Test[3337:3c03] 第 8 次 – {name = (null), num = 10}
2014-11-08 15:19:30.335 Test[3337:3d03] 第 9 次 – {name = (null), num = 11}

7、主队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma mark 7、主队列同步请求
- (void)gcd7
{
    // 获取主队列 dispatch_get_main_queue()
    dispatch_queue_t queue = dispatch_get_main_queue();
 
    NSLog(@"任务开始");
    // 发起一个同步任务并执行10次:dispatch_sync(dispatch_queue_t queue, ^{ code })是同步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_sync(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    NSLog(@"任务结束");
 
    // 结论:主队列同步请求不会进入循环体,因为应用程序在主队列中开启了消息循环,该任务在程序运行时不会结束,因此当前任务未完成,下一个任务永远不会开始。
}

运行结果:
2014-11-08 15:20:50.754 Test[3372:607] 任务开始

8、主队列异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma mark 8、主队列异步请求
- (void)gcd8
{
    // 获取主队列 dispatch_get_main_queue()
    dispatch_queue_t queue = dispatch_get_main_queue();
 
    // 发起一个异步任务并执行10次:dispatch_async(dispatch_queue_t queue, ^{ code })是异步执行函数
    for (int i = 0; i < 10; i++) {
 
        dispatch_async(queue, ^{
            // 打印当前线程
            NSLog(@"第 %d 次 - %@", i, [NSThread currentThread]);
        });
    }
    // 结论:主队列中发起一个异步请求,只在线程1中执行,因为主队列是个串行队列
}

运行结果:
2014-11-08 15:23:08.199 Test[3425:607] 第 0 次 – {name = (null), num = 1}
2014-11-08 15:23:08.203 Test[3425:607] 第 1 次 – {name = (null), num = 1}
2014-11-08 15:23:08.204 Test[3425:607] 第 2 次 – {name = (null), num = 1}
2014-11-08 15:23:08.205 Test[3425:607] 第 3 次 – {name = (null), num = 1}
2014-11-08 15:23:08.205 Test[3425:607] 第 4 次 – {name = (null), num = 1}
2014-11-08 15:23:08.206 Test[3425:607] 第 5 次 – {name = (null), num = 1}
2014-11-08 15:23:08.207 Test[3425:607] 第 6 次 – {name = (null), num = 1}
2014-11-08 15:23:08.210 Test[3425:607] 第 7 次 – {name = (null), num = 1}
2014-11-08 15:23:08.210 Test[3425:607] 第 8 次 – {name = (null), num = 1}
2014-11-08 15:23:08.211 Test[3425:607] 第 9 次 – {name = (null), num = 1}

Leave a Reply