多線程(GCD)

#import "ViewController.h"

@interface ViewController ()

@property(nonatomic,assign)NSInteger count;

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//單利

//? ? static dispatch_once_t onceToken;

//? ? dispatch_once(&onceToken,^{

//

//? ? });

//線程互斥

//創建線程鎖

NSLock *lock =[[NSLock alloc]init];

//為了防止循環引用

self.count =100;//票數

//創建并行隊列

dispatch_queue_t queue =dispatch_queue_create("com.selltikets.www", DISPATCH_QUEUE_CONCURRENT);

__weak ViewController *weakself = self;

for (int i=0; i<10; i++) {

dispatch_async(queue, ^{

[lock lock];//枷鎖

for (int j =0; j<10; j++) {

NSLog(@"買到了第%ld張票",weakself.count);

weakself.count--;

}

[lock unlock];//解鎖

});

}

// Do any additional setup after loading the view, typically from a nib.

}

/*1.GCD是最簡單的多線程,也是效果最高的一種方式,全部是C語言代碼編碼編寫的API,也是是蘋果公司主推的一種多線程

2.GCD 通過queue來實現多線程

3.GCD里面有多重queue 一種是串行serial一種是并行concurrent.

*/

//串行隊列

- (IBAction)serialqueue:(UIButton *)sender {

//關鍵字serial 特點,第一個任務執行完成,第二個任務才開始執行,一次類推

//有兩種方式

#pragma? mark ---串行隊列第一種

//? ? dispatch_queue_t? queue =dispatch_get_main_queue();

//? ? //往隊列里面添加任務

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第一個任務,當前線程%@,是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第二個任務,當前任務是%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第三個任務,當前任務是%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第四個任務,這是當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

#pragma mark ---串行隊列第二種--------------

/*

獲取串行隊列第二種方式:自己創建隊列,

*

*

穿件串行隊列的第二種方式

@Pram "serialQueue" 隊列的名字(蘋果主推使用反向域名去命名)

@pram DISPATCH_QUEUE_SERIAL 隊列的類型

手動創建的串行不在主線程中

*/

//

//? ? dispatch_queue_t queue =dispatch_queue_create("com.serialQueue.www", DISPATCH_QUEUE_SERIAL);

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第一個任務,當前線程是%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第二個任務呀當前線程%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第三個任務,當前任務是:%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第四個任務,當前任務是%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

}

//并行隊列

- (IBAction)concurrentQueue:(UIButton *)sender {

//concurrent 特點:第一個任務執行開始之后,第二個任務,不等第一個執行完畢,直接開始執行.依次類推,后面的任務跟前面的沒有關系,先添加的任務不一定先執行,后面添加的不一定最后執行.并行隊列會根據隊列里面的任務數量CPU使用情況開辟最合適的線程數量,去完成隊列里的任務.

//創建有兩種方式

#pragma mark -----concurentQueue--第一種方式-------

//? ? dispatch_queue_t queue=dispatch_queue_create("com.concurrentQueue.www", DISPATCH_QUEUE_CONCURRENT);

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"%@%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"第一個任務當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"第二個任務當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"第三個任務當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"第四個任務,當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

//? ? });

#pragma mark -----concurrentQueue__第二種創建方式

//創建globalqueue是蘋果里面的全局隊列,有四個優先級 第一個參數DISPATCH_QUEUE_PRIORITY_DEFAULT? 隊列的優先級, 第二個是預留的參數,為了以后使用,目前還沒使用寫0;

//#define DISPATCH_QUEUE_PRIORITY_HIGH 2

//#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0

//#define DISPATCH_QUEUE_PRIORITY_LOW (-2)

//#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN

dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{

NSLog(@"第一個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第二個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第三任務當前線程%@是否主線稱%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第四個任務當前 線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第五個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第六個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第七個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第八個任務當前線程%@是否主線成%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第九個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第十個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

}

//延遲執行代碼(dispatch_after 可以再任何隊列中執行,串行 并行,都可以);

- (IBAction)afterbutton:(UIButton *)sender {

/*

第一種

*/

//? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

//? ? ? ? NSLog(@"%@%d",[NSThread currentThread],[NSThread isMainThread]);

//? ? });

//第二種

dispatch_time_t seconds =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));

//創建一個全局隊列

dispatch_queue_t queue =dispatch_get_global_queue(0, 0);

//添加到隊列中

dispatch_after(seconds, queue, ^{

NSLog(@" 我是延遲任務當前任務線程%@是否是主線程 %d",[NSThread currentThread],[[NSThread currentThread]isMainThread] );

});

}//方法結尾括號

//線程組

- (IBAction)groupbutton:(UIButton *)sender {

//線程組:disoatch_group_t主要是吧一些不想關的任務就歸為一組

//組里面放的是隊列

//dispatch_group_async給組里面的隊列添加任務

//dispatch_group_notify 作用是監聽組里面的任務,等到組里面的任務全部執行完之后,才會執行里面的任務.

//1.創建組

dispatch_group_t group = dispatch_group_create();

//2.創建全局隊列

dispatch_queue_t queue =dispatch_get_global_queue(0, 0);

//3.往組里添加隊列

dispatch_group_async(group, queue, ^{

NSLog(@"我是第一個任務當前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_group_notify(group, queue, ^{

NSLog(@"我是最后一個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_group_async(group, queue, ^{

NSLog(@"這是第二個任務當前線程%@是否主線程%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);

});

dispatch_group_async(group, queue, ^{

NSLog(@"我是第三個任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

}//方法結尾括號

//同時進行讀寫

- (IBAction)readandwriteatsametime:(UIButton *)sender {

//數據庫的讀取 可以并發執行,通過GCD里面的并行去實現

//數據庫的寫入,只能串發執行,通過GCD里面的串行隊列去實現;

//但是真正的項目肯定是既有數據的讀寫也有數據的寫入;如何解決" dispatch _barrier_async 在它之前的任務可以區域并發執行,在他之后的任務也可以并發執行

//創建一個并行隊列

dispatch_queue_t queue =dispatch_queue_create("con.concurrent.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

NSLog(@"第一任務當前線程%@是否主線成%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第二任務,當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第三任務當前先成%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第四線程當前線程%@是否主線成%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第五任務當前任務%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_barrier_async(queue, ^{

NSLog(@"我正在讀取數據%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第六人物當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第七任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第八任務呀當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第九任務當前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);

});

dispatch_async(queue, ^{

NSLog(@"第十個任務當前線程%@是否主線程%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);

});

}

//多次執行

- (IBAction)moretimes:(UIButton *)sender {

NSArray *array =@[@"1",@"2",@"3"];

//同城和數組配合使用

dispatch_queue_t queue =dispatch_get_global_queue(0, 0);

/*

第一個參數 次數

第二個參數 隊列

第三個參數 任務

*/

//index:記錄當前執行的第幾次? ,是小于隨機次數的

dispatch_apply(3, queue, ^(size_t index ) {

NSLog(@"%@",array[index]);

});

}

//async和sync的區別

- (IBAction)syncandasyncdiffrent:(UIButton *)sender {

//async不等block體執行完畢就去執行下面的代碼

//sync 會等block體執行完畢之后才會執行block;

dispatch_queue_t queue=dispatch_get_global_queue(0, 0);

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第一個任務");

//? ? });

//? ? NSLog(@"呵呵");

//? ? dispatch_async(queue, ^{

//? ? ? ? NSLog(@"這是第二個任務");

//? ? });

//? ? NSLog(@"哦");

dispatch_sync(queue, ^{

NSLog(@"第一個任務");

});

NSLog(@"heh");

dispatch_sync(queue, ^{

NSLog(@"第二個任務");

});

NSLog(@"o");

}//

//gcd調用函數指針

- (IBAction)functionpointer:(UIButton *)sender {

dispatch_queue_t queue=dispatch_get_global_queue(0, 0);

/*

第二個參數<#void *context#>函數參數的內容

第三個參數<#dispatch_function_t work#> 函數(函數的返回值為void 參數類型必須為void)

*/

dispatch_async_f(queue, @"hehe", function);

}//

void function(void *context){

NSLog(@"%@",context);

printf("o");

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • #import "ViewController.h" @interface ViewController () @...
    艾克12138閱讀 266評論 0 0
  • 最近頗花了一番功夫把多線程GCD人的一些用法總結出來,一來幫自己鞏固一下知識、二來希望能幫到對這一塊還迷茫...
    人活一世閱讀 296評論 1 1
  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 853評論 0 3
  • 一、基本概念 線程是用來執行任務的,線程徹底執行完任務A才能執行任務B,為了同時執行兩個任務,產生了多線程 1、進...
    空白Null閱讀 727評論 0 3
  • 1.早上兒子賴床,有些賴幾想哭,跟他用了共情方式,使兒子很快接受了,漸漸停止哭鬧,起床了。 2.中午放學回家,兒子...
    軒寧媽閱讀 140評論 0 1