如何充分的利用计算机的有效资源,在并发以前使用多线程解决,然而不少东西须要程序员来考虑,如何建立合理数目的线程,如何控制线程之间有效运行互不影响。并发很好的解决了这样的问题。在学习的过程当中,咱们常常看到并发,串行,异步,同步这样的自研。它们之间有以下4种组合:程序员
1.串行+同步多线程
- (void)serialSync { dispatch_queue_t serialQueue = dispatch_queue_create("com.tian.lawrence", DISPATCH_QUEUE_SERIAL); NSLog(@"1 - %@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ NSLog(@"2 - %@", [NSThread currentThread]); }); dispatch_sync(serialQueue, ^{ NSLog(@"3 - %@", [NSThread currentThread]); }); NSLog(@"4 - %@", [NSThread currentThread]); }
结果:并发
2017-08-21 08:37:44.619 Chapter2[1772:68997] 1 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.619 Chapter2[1772:68997] 2 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.620 Chapter2[1772:68997] 3 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.620 Chapter2[1772:68997] 4 - <NSThread: 0x608000074840>{number = 1, name = main}
能够看到该组合,没有建立新的线程,在当前线程执行任务。首先队列是先进先出的原则,当第一个同步任务插入队列时,阻塞线程,须要执行队列中的任务。由于队列中只有它本身,因此执行。同理,第二个第三个...也是这样的状况。异步
2.串行+异步async
- (void)serialAsync { dispatch_queue_t serialQueue = dispatch_queue_create("com.tian.lawrence", DISPATCH_QUEUE_SERIAL); NSLog(@"1 - %@", [NSThread currentThread]); dispatch_async(serialQueue, ^{ NSLog(@"2 - %@", [NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"3 - %@", [NSThread currentThread]); }); NSLog(@"4 - %@", [NSThread currentThread]); }
结果:学习
2017-08-21 08:37:44.620 Chapter2[1772:68997] 1 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.620 Chapter2[1772:68997] 4 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.621 Chapter2[1772:69315] 2 - <NSThread: 0x608000262480>{number = 3, name = (null)} 2017-08-21 08:37:44.621 Chapter2[1772:69315] 3 - <NSThread: 0x608000262480>{number = 3, name = (null)}
当前组合,只建立了一条新的线程。由于是异步任务,因此在插入队列时,不会阻塞,待插入结束后,而后依次执行队列中的任务。spa
3.并行+同步线程
- (void)concurrentSync { dispatch_queue_t serialQueue = dispatch_queue_create("com.tian.lawrence", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1 - %@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ NSLog(@"2 - %@", [NSThread currentThread]); }); dispatch_sync(serialQueue, ^{ NSLog(@"3 - %@", [NSThread currentThread]); }); NSLog(@"4 - %@", [NSThread currentThread]); }
结果code
2017-08-21 08:37:44.621 Chapter2[1772:68997] 1 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.621 Chapter2[1772:68997] 2 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.622 Chapter2[1772:68997] 3 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.622 Chapter2[1772:68997] 4 - <NSThread: 0x608000074840>{number = 1, name = main}
在当前队列执行任务,没有建立新的线程。blog
4.并行+异步
- (void)concurrentAsync { dispatch_queue_t serialQueue = dispatch_queue_create("com.tian.lawrence", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1 - %@", [NSThread currentThread]); dispatch_async(serialQueue, ^{ NSLog(@"2 - %@", [NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"3 - %@", [NSThread currentThread]); }); NSLog(@"4 - %@", [NSThread currentThread]); }
结果
2017-08-21 08:37:44.624 Chapter2[1772:68997] 1 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.624 Chapter2[1772:68997] 4 - <NSThread: 0x608000074840>{number = 1, name = main} 2017-08-21 08:37:44.624 Chapter2[1772:69315] 2 - <NSThread: 0x608000262480>{number = 3, name = (null)} 2017-08-21 08:37:44.624 Chapter2[1772:69312] 3 - <NSThread: 0x600000260000>{number = 4, name = (null)}
当前组合,按照子任务的数目建立相应数目的线程,达到了并发的目的。由于异步,在插入到队列的时候,不会阻塞。弹出队列的执行时,会建立不一样的线程去执行子任务,子任务执行的结果的输出是无序的,子任务之间相互不影响。
附图一张,便于理解: