如何充分的利用計算機的有效資源,在併發以前使用多線程解決,然而不少東西須要程序員來考慮,如何建立合理數目的線程,如何控制線程之間有效運行互不影響。併發很好的解決了這樣的問題。在學習的過程當中,咱們常常看到併發,串行,異步,同步這樣的自研。它們之間有以下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)}
當前組合,按照子任務的數目建立相應數目的線程,達到了併發的目的。由於異步,在插入到隊列的時候,不會阻塞。彈出隊列的執行時,會建立不一樣的線程去執行子任務,子任務執行的結果的輸出是無序的,子任務之間相互不影響。
附圖一張,便於理解: