#import "JYMoreThread.h" /** http://www.cocoachina.com/articles/19769 */ @implementation JYMoreThread - (void)setupThread { [self syncMain]; } /** 串行同步 */ - (void)syncSerial { NSLog(@"**************串行同步***************"); // 串行队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL); // 同步执行 dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行同步1 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行同步2 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行同步3 %@",[NSThread currentThread]); } }); } /** 串行异步 */ - (void)asyncSerial { NSLog(@"**************串行异步***************"); // 串行队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL); // 同步执行 dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行异步1 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行异步2 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"串行异步3 %@",[NSThread currentThread]); } }); } /** 并发同步 */ - (void)syncConcurrent { NSLog(@"**************并发同步***************"); // 并发队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT); // 同步执行 dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发同步1 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发同步2 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发同步3 %@",[NSThread currentThread]); } }); } /** 并发异步 */ - (void)asyncConcurrent { NSLog(@"**************并发异步***************"); // 并发队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT); // 异步执行 dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发异步1 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发异步2 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"并发异步3 %@",[NSThread currentThread]); } }); } /** 主队列同步 */ - (void)syncMain { /** 主队列同步造成死锁的原因: 如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。 而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。 可是主线程现在正在处理syncMain方法,任务需要等syncMain执行完才能执行。 syncMain执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。 这样syncMain方法和第一个任务就开始了互相等待,形成了死锁。 */ NSLog(@"**************主队列同步,放到主线程会死锁***************"); // 主队列 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列同步1 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列同步2 %@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列同步3 %@",[NSThread currentThread]); } }); } /** 主队列异步 */ - (void)asyncMain { NSLog(@"**************主队列异步***************"); // 主队列 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列异步1 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列异步2 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"主队列异步3 %@",[NSThread currentThread]); } }); } // GCD栅栏 // 当任务需要异步进行,但是这些任务需要分成两组来执行,第一组完成之后才能进行第二组的操作。这时候就用了到GCD的栅栏方法dispatch_barrier_async。 - (void)barrierGCD { // 并发队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT); // 异步执行 dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"栅栏:并发异步1 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"栅栏:并发异步2 %@",[NSThread currentThread]); } }); // dispatch_barrier_async(queue, ^{ // NSLog(@"------------barrier------------%@", [NSThread currentThread]); // NSLog(@"******* 并发异步执行,但是34一定在12后面 *********"); // }); dispatch_barrier_sync(queue, ^{ NSLog(@"------------barrier------------%@", [NSThread currentThread]); NSLog(@"******* 并发异步执行,但是34一定在12后面 *********"); }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"栅栏:并发异步3 %@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 3; i++) { NSLog(@"栅栏:并发异步4 %@",[NSThread currentThread]); } }); } - (void)barrierGCD22 { // 并发队列 dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT); // 异步执行 dispatch_async(queue, ^{ NSLog(@"栅栏:并发异步1 %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"栅栏:并发异步2 %@",[NSThread currentThread]); }); // dispatch_barrier_sync(queue, ^{ // NSLog(@"++++ barrier sync +++++"); // }); dispatch_barrier_async(queue, ^{ NSLog(@"++++ barrier async +++++"); }); NSLog(@"洪城河"); dispatch_async(queue, ^{ NSLog(@"栅栏:并发异步3 %@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"栅栏:并发异步4 %@",[NSThread currentThread]); }); NSLog(@"last"); } - (void)applyGCD { NSLog(@"************** GCD快速迭代 ***************"); // 并发队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); // dispatch_apply几乎同时遍历多个数字 dispatch_apply(7, queue, ^(size_t index) { NSLog(@"dispatch_apply:%zd======%@",index, [NSThread currentThread]); }); } - (void)testGroup { /** 队列组有下面几个特点: 1、所有的任务会并发的执行(不按序)。 2、所有的异步函数都添加到队列中,然后再纳入队列组的监听范围。 3、使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。 */ dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ NSLog(@"队列组1:有一个耗时操作完成!"); }); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ NSLog(@"队列组2:有一个耗时操作完成!"); }); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ NSLog(@"队列组3:有一个耗时操作完成!"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"队列组4:前面的耗时操作都完成了,回到主线程进行相关操作"); }); } -(void)dispatchSignal{ //crate的value表示,最多几个资源可访问 dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //任务1 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 1"); sleep(1); NSLog(@"complete task 1"); dispatch_semaphore_signal(semaphore); }); //任务2 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 2"); sleep(1); NSLog(@"complete task 2"); dispatch_semaphore_signal(semaphore); }); //任务3 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 3"); sleep(1); NSLog(@"complete task 3"); dispatch_semaphore_signal(semaphore); }); //任务4 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 4"); sleep(1); NSLog(@"complete task 4"); dispatch_semaphore_signal(semaphore); }); //任务5 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 5"); sleep(1); NSLog(@"complete task 5"); dispatch_semaphore_signal(semaphore); }); //任务6 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 6"); sleep(1); NSLog(@"complete task 6"); dispatch_semaphore_signal(semaphore); }); } - (void)testNSInvocationOperation { // 创建NSInvocationOperation NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperation) object:nil]; // 开始执行操作 [invocationOperation start]; } - (void)invocationOperation { // 打印结果如下,得到结论:程序在主线程执行,没有开启新线程。 NSLog(@"NSInvocationOperation包含的任务,没有加入队列========%@", [NSThread currentThread]); } - (void)testNSBlockOperation { // 可以看出:主线程执行,没有开启新线程 // 同样的,NSBlockOperation可以配合队列NSOperationQueue来实现多线程 // 把任务放到block中 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"NSBlockOperation包含的任务,没有加入队列========%@", [NSThread currentThread]); }]; [blockOperation start]; } - (void)testNSBlockOperationExecution { /** 执行结果如下,可以看出,NSBlockOperation创建时block中的任务是在主线程执行,而运用addExecutionBlock加入的任务是在子线程执行的。 */ // NSBlockOperation有一个方法addExecutionBlock:,通过这个方法可以让NSBlockOperation实现多线程。 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"NSBlockOperation运用addExecutionBlock主任务========%@", [NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务1========%@", [NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务2========%@", [NSThread currentThread]); }]; [blockOperation addExecutionBlock:^{ NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务3========%@", [NSThread currentThread]); }]; [blockOperation start]; } - (void)testOperationQueue { // 创建队列,默认并发 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 创建操作,NSInvocationOperation NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperationAddOperation) object:nil]; // 创建操作,NSBlockOperation NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"addOperation把任务添加到队列======%@", [NSThread currentThread]); } }]; [queue addOperation:invocationOperation]; [queue addOperation:blockOperation]; } - (void)invocationOperationAddOperation { NSLog(@"invocationOperation===aaddOperation把任务添加到队列====%@", [NSThread currentThread]); } - (void)testAddOperationWithBlock { // 创建队列,默认并发 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 添加操作到队列 [queue addOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"addOperationWithBlock把任务添加到队列======%@", [NSThread currentThread]); } }]; } // 运用最大并发数实现串行 - (void)testMaxConcurrentOperationCount { // 创建队列,默认并发 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 最大并发数为1,串行 // queue.maxConcurrentOperationCount = 1; // 最大并发数为2,并发 queue.maxConcurrentOperationCount = 2; // 添加操作到队列 [queue addOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"addOperationWithBlock把任务添加到队列1======%@", [NSThread currentThread]); } }]; // 添加操作到队列 [queue addOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"addOperationWithBlock把任务添加到队列2======%@", [NSThread currentThread]); } }]; // 添加操作到队列 [queue addOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"addOperationWithBlock把任务添加到队列3======%@", [NSThread currentThread]); } }]; } - (void)testAddDependency { // 并发队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 操作1 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 3; i++) { NSLog(@"operation1======%@", [NSThread currentThread]); } }]; // 操作2 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"****operation2依赖于operation1,只有当operation1执行完毕,operation2才会执行****"); for (int i = 0; i < 3; i++) { NSLog(@"operation2======%@", [NSThread currentThread]); } }]; // 使操作2依赖于操作1 [operation2 addDependency:operation1]; // 把操作加入队列 [queue addOperation:operation1]; [queue addOperation:operation2]; } @end