任务:需要执行的操作
队列:线性队列 并发队列 同步队列
几种组合方式
同步+并发
执行特点:
同步队列+同步
异步+并发
异步+同步
常用三种方式创建
dispatch_get_main_queue
dispatc_queue_create
dispatch_global_queue
三种队列:
串行队列
并发队列
主队列
两种执行方式
dispatch_async(queue, ^{
//异步执行代码
});
dispatch_sync(queue, ^{
//同步执行代码
});
不同执行结果
- (void)syncTaskWithSerial {
NSLog(@"currentThread:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t serialQueue = dispatch_queue_create("com.cao.thread.demo", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
NSLog(@"currentThread-1:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(serialQueue, ^{
NSLog(@"currentThread-2:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(serialQueue, ^{
NSLog(@"currentThread-3:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
//output
// ThreadTest[505:64898] currentThread:{number = 1, name = main}
// ThreadTest[505:64898] isMainThread:YES
// ThreadTest[505:64898] currentThread-1:{number = 1, name = main}
// ThreadTest[505:64898] isMainThread:YES
// ThreadTest[505:64898] currentThread-2:{number = 1, name = main}
// ThreadTest[505:64898] isMainThread:YES
// ThreadTest[505:64898] currentThread-3:{number = 1, name = main}
// ThreadTest[505:64898] isMainThread:YES
}
没有开启新线程
任务顺序执行
串行队列+异步执行
//串行队列 + 异步执行
- (void)asyncTaskWithSerial {
NSLog(@"currentThread:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t serialQueue = dispatch_queue_create("com.cao.thread.demo", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
NSLog(@"currentThread-1:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(serialQueue, ^{
NSLog(@"currentThread-2:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(serialQueue, ^{
NSLog(@"currentThread-3:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
//output
// ThreadTest[509:65509] currentThread:{number = 1, name = main}
// ThreadTest[509:65509] isMainThread:YES
// ThreadTest[509:65546] currentThread-1:{number = 3, name = (null)}
// ThreadTest[509:65546] isMainThread:NO
// ThreadTest[509:65546] currentThread-2:{number = 3, name = (null)}
// ThreadTest[509:65546] isMainThread:NO
// ThreadTest[509:65546] currentThread-3:{number = 3, name = (null)}
// ThreadTest[509:65546] isMainThread:NO
}
开启了新线程
顺序执行了(虽然是异步任务,但是因为是同步队列,执行顺序依然是同步)
并发队列+ 同步
- (void)syncTaskWithConcurrent{
NSLog(@"currentThread:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t concurrentQueue = dispatch_queue_create("coms.cao.thread.demo", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(concurrentQueue, ^{
NSLog(@"currentThread-1:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(concurrentQueue, ^{
NSLog(@"currentThread-2:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(concurrentQueue, ^{
NSLog(@"currentThread-3:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
// 预计:1. 开新线程 一个 (错误) 2. 顺序执行
//Output
// ThreadTest[518:66775] currentThread:{number = 1, name = main} isMainThread:YES
// ThreadTest[518:66775] currentThread-1:{number = 1, name = main} isMainThread:YES
// ThreadTest[518:66775] currentThread-2:{number = 1, name = main} isMainThread:YES
// ThreadTest[518:66775] currentThread-3:{number = 1, name = main} isMainThread:YES
}
未开启新线程
顺序执行
并发队列+ 异步
- (void)asyncTaskWithConcuarrent{
NSLog(@"currentThread:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t concurrentQueue = dispatch_queue_create("coms.cao.thread.demo", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
NSLog(@"currentThread-1:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"currentThread-2:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"currentThread-3:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
// 预计:1. 开新线程 2. 异步执行
//Output
// ThreadTest[521:67287] currentThread:{number = 1, name = main} isMainThread:YES
// ThreadTest[521:67326] currentThread-2:{number = 3, name = (null)} isMainThread:NO
// ThreadTest[521:67326] currentThread-3:{number = 3, name = (null)} isMainThread:NO
// ThreadTest[521:67327] currentThread-1:{number = 4, name = (null)} isMainThread:NO
}
开新线程
异步执行
主队列+ 同步
Thread 1: EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe)
- (void)syncTaskWithMain{
NSLog(@"currentThread:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
NSLog(@"currentThread-1:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(mainQueue, ^{
NSLog(@"currentThread-2:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_sync(mainQueue, ^{
NSLog(@"currentThread-3:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
}
// 死锁:
因为是同步执行,任务等待函数调用处执行完毕,然后执行。 函数调用处执行完毕需要同步任务执行完,两者相互等待发生死锁
- (void)asyncTaskWithMain{
NSLog(@"currentThread:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"currentThread-1:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(mainQueue, ^{
NSLog(@"currentThread-2:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
dispatch_async(mainQueue, ^{
NSLog(@"currentThread-3:%@ isMainThread:%@",[NSThread currentThread],[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
//output
// ThreadTest[531:68798] currentThread:{number = 1, name = main} isMainThread:YES
// ThreadTest[531:68798] currentThread-1:{number = 1, name = main} isMainThread:YES
// ThreadTest[531:68798] currentThread-2:{number = 1, name = main} isMainThread:YES
// ThreadTest[531:68798] currentThread-3:{number = 1, name = main} isMainThread:YES
}
串行异步+串行同步
(void)testEmbedExcute {
NSLog(@"currentThread:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_queue_t serialQueue = dispatch_queue_create("com.cao.thread.demo", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
NSLog(@"currentThread-1:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
dispatch_sync(serialQueue, ^{
NSLog(@"currentThread-2:%@",[NSThread currentThread]);
NSLog(@"isMainThread:%@",[[NSThread currentThread] isMainThread] ? @"YES":@"NO");
});
});
}
Thread 2: EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe)
发生死锁:
- (void)barrierTask {
dispatch_queue_t queue = dispatch_queue_create("com.cao.thread.demo", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"start");
dispatch_async(queue, ^{
NSLog(@"currentThread-1:%@",[NSThread currentThread]);
});
dispatch_barrier_sync(queue, ^{
NSLog(@"currentThread-2:%@",[NSThread currentThread]);
});
dispatch_barrier_sync(queue, ^{
NSLog(@"currentThread-3:%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"currentThread-4:%@",[NSThread currentThread]);
});
// ThreadTest[555:73805] start
// ThreadTest[555:73850] currentThread-1:{number = 3, name = (null)}
// ThreadTest[555:73805] currentThread-2:{number = 1, name = main}
// ThreadTest[555:73805] currentThread-3:{number = 1, name = main}
// ThreadTest[555:73850] currentThread-4:{number = 3, name = (null)}
}
1.阻塞线程同步执行
2.延迟执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5), dispatch_get_main_queue(), ^{
NSLog(@"after-1:%@",[NSThread currentThread]);
});
3.调度组
Groups allow you to aggregate a set of tasks and synchronize behaviors on the group. You attach multiple blocks to a group and schedule them for asynchronous execution on the same queue or different queues. When all blocks finish executing, the group executes its completion handler. You can also wait synchronously for all blocks in the group to finish executing.
调度组简单就是把异步任务进行分组,等待所有的任分组都执行完毕后再回到指定的线程执行任务。
接口:
创建:
dispatch_group_create
将任务添加到队列中
dispatch_group_async 将任务添加到队列中,然后将队列添加到调度组中
dispatch_group_notify 回到指定线程执行任务
两个成对出现
dispatch_group_leave 将实现队列添加到调度组
dispatch_group_wait 阻塞当前线程
- (void)groupNotifyTest{
NSLog(@"current thread:%@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-1:%@",[NSThread currentThread]);
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-2:%@",[NSThread currentThread]);
});
//异步任务执行完毕后 执行添加的通知
dispatch_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-3:%@",[NSThread currentThread]);
NSLog(@"group-end");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"dispatch_group_wait后继续执行任务");
// ThreadTest[598:81370] current thread:{number = 1, name = main}
// ThreadTest[598:81406] current thread-1:{number = 3, name = (null)}
// ThreadTest[598:81407] current thread-2:{number = 4, name = (null)}
// ThreadTest[598:81370] dispatch_group_wait后继续执行任务
// ThreadTest[598:81370] current thread-3:{number = 1, name = main}
// ThreadTest[598:81370] group-end
}
dispatch_group_enter和dispatch_group_leave对实现将队列添加到调度组的情况,dispatch_group_enter 标志着在group的任务数+1,dispatch_group_leave标志在group中的任务数-1,表示已经完成了一个任务。
- (void)groupEnterTest {
NSLog(@"current thread:%@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-1:%@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-2:%@",[NSThread currentThread]);
dispatch_group_leave(group);
});
//异步任务执行完毕后 执行添加的通知
dispatch_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"current thread-3:%@",[NSThread currentThread]);
NSLog(@"group-end");
});
}
成对出现
- (void)semaphoreTest {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block int a =0;
while (a<5) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"a里面的值:%d",a);
dispatch_semaphore_signal(semaphore);
a++;
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
NSLog(@"外面的a的值:%d",a);
}
An object that coordinates the processing of specific low-level system events, such as file-system events, timers, and UNIX signals.