#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");
}