簡書中比較全的多線程執行,在這裏保存下鏈接傳送門
//
// ViewController.m
// syn_asyn
//
// Created by mac on 2018/6/20.
// Copyright © 2018年 Gooou. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 使用 NSThread 的 detachNewThreadSelector 方法會創建線程,並自動啓動線程執行 selector 任務,不會造成卡頓,任務三個都加在主線程中執行,而主線程沒有任務執行,所以不會造成崩潰。
// [NSThread detachNewThreadSelector:@selector(sync_mainQueue) toTarget:self withObject:nil];
[self groupEnterAndLeave];
}
/*同步執行,併發隊列*/
-(void)sync_ConcurrentQueue{
NSLog(@"currentThread--%@",[NSThread currentThread]);//打印當前線程
NSLog(@"syncConcurrent--begin");
//串行隊列
dispatch_queue_t queue=dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
//同步執行
dispatch_sync(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_sync(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"syncConcurrent--end");
}
/*異步執行併發隊列:可開啓多個線程,任務交替執行*/
-(void)async_ConcurrentQueue{
/*異步執行+併發隊列
特點:可以開啓多個線程,任務交替執行
*/
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"asyncConcurrent--begin");
dispatch_queue_t queue=dispatch_queue_create("net.bujige.testQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_async(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"asyncConcurrent--end");
}
/*同步執行+串行隊列*/
-(void)sync_serialQueue{
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"syncConcurrent--begin");
dispatch_queue_t queue=dispatch_queue_create("net.bujige.testQueue",DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_sync(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"syncConcurrent--end");
}
/*異步執行+串行隊列*/
-(void)async_serialQueue{
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"asyncConcurrent--begin");
dispatch_queue_t queue=dispatch_queue_create("net.bujige.testQueue",DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_async(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"asyncConcurrent--end");
}
/*同步執行+主隊列
特點:互相等待卡主不執行
不會開啓新線程,執行完一個任務,執行下一個任務
會產生崩潰
*/
-(void)sync_mainQueue{
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"syncMain--begin");
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_async(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_sync(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"syncMain--end");
}
/*異步執行+主隊列
只在主線程執行任務,執行完一個任務,再執行下一個任務
所有任務都是在當前線程(主線程)中執行的,並沒有開啓新的線程(雖然異步執行具備開啓線程的能力,但因爲是主隊列,所以所有任務都在主線程中)
*/
-(void)async_mainQueue{
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"asyncMain--begin");
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_async(queue, ^{
//追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];//模擬操作耗時
NSLog(@"1--%@",[NSThread currentThread]);//打印當前線程
}
});
dispatch_async(queue, ^{
//追加任務2
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
//追加任務3
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3--%@",[NSThread currentThread]);
}
});
NSLog(@"asyncMain--end");
}
/*
線程間的通訊
*/
-(void)communication{
//獲取全局併發隊列
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//獲取主隊列
dispatch_queue_t mainQueue=dispatch_get_main_queue();
dispatch_async(queue, ^{
//異步追加任務
for (int i=0; i<2; ++i) {
[NSThread sleepForTimeInterval:2];
NSLog(@"1--%@",[NSThread currentThread]);
}
//回到主線程
dispatch_async(mainQueue, ^{
//追加在主線程中執行的任務
[NSThread sleepForTimeInterval:2];
NSLog(@"2--%@",[NSThread currentThread]);
});
});
}
/*
柵欄方法:需要異步執行兩組操作,而且第一組操作完成之後,才能開始執行第二組操作,
*/
-(void)barrier{
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]);// 打印當前線程
}
});
dispatch_async(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]);// 打印當前線程
}
});
dispatch_barrier_sync(queue, ^{
// 追加任務 barrier
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"barrier---%@",[NSThread currentThread]);// 打印當前線程
}
});
dispatch_async(queue, ^{
// 追加任務3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]);// 打印當前線程
}
});
dispatch_async(queue, ^{
// 追加任務4
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"4---%@",[NSThread currentThread]);// 打印當前線程
}
});
}
/*
延時執行方法
*/
-(void)after{
NSLog(@"currentThread--%@",[NSThread currentThread]);
NSLog(@"asyncMain--begin");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2.0秒之後異步追加任務到主隊列中,並開始執行
NSLog(@"after--%@",[NSThread currentThread]);
});
}
/*只執行一次
多線程環境下,保證線程安全
*/
-(void)once{
static dispatch_queue_t onceToken;
// dispatch_once(&onceToken, ^{
// //執行代碼
// });
}
/*
dispatch_apply按照指定的次數將指定的任務添加到指定的隊列中取,並等待全部隊列執行結束
*/
-(void)apply{
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"apply--begin");
dispatch_apply(6, queue, ^(size_t index) {
NSLog(@"%zd--%@",index,[NSThread currentThread]);
});
NSLog(@"apply--end");
}
/*
分別異步執行2個耗時任務,然後當2個耗時任務執行完成之後回到主線程執行任務。
*/
-(void)groupNofity{
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當前線程
NSLog(@"group---begin");
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當前線程
}
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當前線程
}
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的異步任務1、任務2都執行完畢後,回到主線程執行下邊任務
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當前線程
}
NSLog(@"group---end");
});
}
/*暫停當前線程,等待指定的group中的任務執行完成後,纔會往下執行
*/
-(void)groupWait{
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當前線程
NSLog(@"group---begin");
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當前線程
}
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當前線程
}
});
//等待上面的任務全部完成後,會往下繼續執行(會阻塞當前線程)
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"group---end");
}
- (void)groupEnterAndLeave
{
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當前線程
NSLog(@"group---begin");
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_async(queue, ^{
// 追加任務1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當前線程
}
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
// 追加任務2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當前線程
}
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的異步操作都執行完畢後,回到主線程.
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當前線程
}
NSLog(@"group---end");
});
}
@end