并发队列
特点:同时调度多个任务(注意:也是按FIFO调度),不会等待上一个任务完成,再调度下一个。
一、并发队列 异步任务
为每个任务新创建一个线程执行。
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.my.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
NSLog(@"并发队列 异步任务0: %@", [NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
sleep(4);
NSLog(@"并发队列 异步任务1: %@", [NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
sleep(3);
NSLog(@"并发队列 异步任务2: %@", [NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
sleep(2);
NSLog(@"并发队列 异步任务3: %@", [NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
sleep(1);
NSLog(@"并发队列 异步任务4: %@", [NSThread currentThread]);
});
--------并发队列 异步任务---------------
2018-03-13 10:39:11.282717+0800 GCDDemo[61398:17145606] 并发队列 异步任务0: <NSThread: 0x60400027ab40>{number = 3, name = (null)}
2018-03-13 10:39:12.287176+0800 GCDDemo[61398:17145602] 并发队列 异步任务4: <NSThread: 0x6040006616c0>{number = 4, name = (null)}
2018-03-13 10:39:13.287166+0800 GCDDemo[61398:17145605] 并发队列 异步任务3: <NSThread: 0x60000047efc0>{number = 5, name = (null)}
2018-03-13 10:39:14.287177+0800 GCDDemo[61398:17145603] 并发队列 异步任务2: <NSThread: 0x60400047c900>{number = 6, name = (null)}
2018-03-13 10:39:15.287222+0800 GCDDemo[61398:17145604] 并发队列 异步任务1: <NSThread: 0x60000047ee00>{number = 7, name = (null)}
二、并发队列 同步任务
在当前线程顺序执行;
虽然是并发队列,但由于是同步任务,当上一个任务未完成时,会阻塞当前线程,下一个任务也就无法执行。所以也是顺序执行的。
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.my.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(concurrentQueue, ^{
sleep(4);
NSLog(@"并发队列 同步任务1: %@", [NSThread currentThread]);
});
dispatch_sync(concurrentQueue, ^{
sleep(3);
NSLog(@"并发队列 同步任务2: %@", [NSThread currentThread]);
});
dispatch_sync(concurrentQueue, ^{
sleep(2);
NSLog(@"并发队列 同步任务3: %@", [NSThread currentThread]);
});
dispatch_sync(concurrentQueue, ^{
sleep(1);
NSLog(@"并发队列 同步任务4: %@", [NSThread currentThread]);
});
2018-03-13 10:40:38.029652+0800 GCDDemo[61453:17148595] 并发队列 同步任务1: <NSThread: 0x6000000778c0>{number = 1, name = main}
2018-03-13 10:40:41.030824+0800 GCDDemo[61453:17148595] 并发队列 同步任务2: <NSThread: 0x6000000778c0>{number = 1, name = main}
2018-03-13 10:40:43.032137+0800 GCDDemo[61453:17148595] 并发队列 同步任务3: <NSThread: 0x6000000778c0>{number = 1, name = main}
2018-03-13 10:40:44.033434+0800 GCDDemo[61453:17148595] 并发队列 同步任务4: <NSThread: 0x6000000778c0>{number = 1, name = main}
串行队列
特点: 顺序的调度任务,上一个任务执行完毕,才会调度下一个任务。
一、串行队列 异步执行
创建一个新的线程,在新的线程中顺序执行。
虽然是异步任务,但是由于是同步队列,所以会在同一个线程上顺序调度,当前线程完成上一个任务时,才会执行下一个任务。
dispatch_queue_t serialQueue = dispatch_queue_create("com.my.serial", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
sleep(4);
NSLog(@"串行队列 异步任务1: %@", [NSThread currentThread]);
});
dispatch_async(serialQueue, ^{
sleep(3);
NSLog(@"串行队列 异步任务2: %@", [NSThread currentThread]);
});
dispatch_async(serialQueue, ^{
sleep(2);
NSLog(@"串行队列 异步任务3: %@", [NSThread currentThread]);
});
dispatch_async(serialQueue, ^{
sleep(1);
NSLog(@"串行队列 异步任务4: %@", [NSThread currentThread]);
});
2018-03-13 10:54:18.848320+0800 GCDDemo[61918:17171634] 串行队列 异步任务1: <NSThread: 0x6000002723c0>{number = 3, name = (null)}
2018-03-13 10:54:21.853179+0800 GCDDemo[61918:17171634] 串行队列 异步任务2: <NSThread: 0x6000002723c0>{number = 3, name = (null)}
2018-03-13 10:54:23.857731+0800 GCDDemo[61918:17171634] 串行队列 异步任务3: <NSThread: 0x6000002723c0>{number = 3, name = (null)}
2018-03-13 10:54:24.861741+0800 GCDDemo[61918:17171634] 串行队列 异步任务4: <NSThread: 0x6000002723c0>{number = 3, name = (null)}
二、串行队列 同步执行
顺序的在当前线程执行。
dispatch_queue_t serialQueue = dispatch_queue_create("com.my.serial", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
sleep(4);
NSLog(@"串行队列 同步任务1: %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
sleep(3);
NSLog(@"串行队列 同步任务2: %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
sleep(2);
NSLog(@"串行队列 同步任务3: %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
sleep(1);
NSLog(@"串行队列 同步任务4: %@", [NSThread currentThread]);
});
2018-03-13 10:55:29.318125+0800 GCDDemo[61966:17173944] 串行队列 同步任务1: <NSThread: 0x600000071d40>{number = 1, name = main}
2018-03-13 10:55:32.318892+0800 GCDDemo[61966:17173944] 串行队列 同步任务2: <NSThread: 0x600000071d40>{number = 1, name = main}
2018-03-13 10:55:34.319660+0800 GCDDemo[61966:17173944] 串行队列 同步任务3: <NSThread: 0x600000071d40>{number = 1, name = main}
2018-03-13 10:55:35.320929+0800 GCDDemo[61966:17173944] 串行队列 同步任务4: <NSThread: 0x600000071d40>{number = 1, name = main}
主队列(main queue)
特点:
- 不会开启线程,所有任务都在主线程执行,无论同步还是异步;
- 上一个任务执行完毕,才会调度下一个任务。(串行队列的性质)
一、主队列 异步任务
在主线程顺序执行。
dispatch_async(dispatch_get_main_queue(), ^{
sleep(4);
NSLog(@"主队列 异步任务1:%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_main_queue(), ^{
sleep(3);
NSLog(@"主队列 异步任务2:%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_main_queue(), ^{
sleep(2);
NSLog(@"主队列 异步任务3:%@", [NSThread currentThread]);
});
dispatch_async(dispatch_get_main_queue(), ^{
sleep(1);
NSLog(@"主队列 异步任务4:%@", [NSThread currentThread]);
});
2018-03-13 10:58:17.316804+0800 GCDDemo[62068:17179639] 主队列 异步任务1:<NSThread: 0x604000262540>{number = 1, name = main}
2018-03-13 10:58:20.318195+0800 GCDDemo[62068:17179639] 主队列 异步任务2:<NSThread: 0x604000262540>{number = 1, name = main}
2018-03-13 10:58:22.318997+0800 GCDDemo[62068:17179639] 主队列 异步任务3:<NSThread: 0x604000262540>{number = 1, name = main}
2018-03-13 10:58:23.320285+0800 GCDDemo[62068:17179639] 主队列 异步任务4:<NSThread: 0x604000262540>{number = 1, name = main}
二、主队列 同步任务
死锁
dispatch_sync会把一个同步任务追加到主队列(main queue)的队尾,同时阻塞当前线程。由于是同步队列,所以只有当该任务之前的所有任务调度执行完成以后,才会调度该任务。但是由于当前线程被阻塞了,之前的任务完成不了,然后也就无法调度当前任务,这就形成了死锁。
也就是说,任务队列等待线程完成任务,线程等待任务队列调度同步任务,相互等待,也就死锁了。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"主队列 同步任务1:%@", [NSThread currentThread]);
});