#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,^{
//
//? ? });
//線程互斥
//創(chuàng)建線程鎖
NSLock *lock =[[NSLock alloc]init];
//為了防止循環(huán)引用
self.count =100;//票數(shù)
//創(chuàng)建并行隊(duì)列
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來實(shí)現(xiàn)多線程
3.GCD里面有多重queue 一種是串行serial一種是并行concurrent.
*/
//串行隊(duì)列
- (IBAction)serialqueue:(UIButton *)sender {
//關(guān)鍵字serial 特點(diǎn),第一個(gè)任務(wù)執(zhí)行完成,第二個(gè)任務(wù)才開始執(zhí)行,一次類推
//有兩種方式
#pragma? mark ---串行隊(duì)列第一種
//? ? dispatch_queue_t? queue =dispatch_get_main_queue();
//? ? //往隊(duì)列里面添加任務(wù)
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第一個(gè)任務(wù),當(dāng)前線程%@,是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第二個(gè)任務(wù),當(dāng)前任務(wù)是%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第三個(gè)任務(wù),當(dāng)前任務(wù)是%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第四個(gè)任務(wù),這是當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
#pragma mark ---串行隊(duì)列第二種--------------
/*
獲取串行隊(duì)列第二種方式:自己創(chuàng)建隊(duì)列,
*
*
穿件串行隊(duì)列的第二種方式
@Pram "serialQueue" 隊(duì)列的名字(蘋果主推使用反向域名去命名)
@pram DISPATCH_QUEUE_SERIAL 隊(duì)列的類型
手動(dòng)創(chuàng)建的串行不在主線程中
*/
//
//? ? dispatch_queue_t queue =dispatch_queue_create("com.serialQueue.www", DISPATCH_QUEUE_SERIAL);
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第一個(gè)任務(wù),當(dāng)前線程是%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第二個(gè)任務(wù)呀當(dāng)前線程%@,是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第三個(gè)任務(wù),當(dāng)前任務(wù)是:%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第四個(gè)任務(wù),當(dāng)前任務(wù)是%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
}
//并行隊(duì)列
- (IBAction)concurrentQueue:(UIButton *)sender {
//concurrent 特點(diǎn):第一個(gè)任務(wù)執(zhí)行開始之后,第二個(gè)任務(wù),不等第一個(gè)執(zhí)行完畢,直接開始執(zhí)行.依次類推,后面的任務(wù)跟前面的沒有關(guān)系,先添加的任務(wù)不一定先執(zhí)行,后面添加的不一定最后執(zhí)行.并行隊(duì)列會(huì)根據(jù)隊(duì)列里面的任務(wù)數(shù)量CPU使用情況開辟最合適的線程數(shù)量,去完成隊(duì)列里的任務(wù).
//創(chuàng)建有兩種方式
#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(@"第一個(gè)任務(wù)當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"第二個(gè)任務(wù)當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"第三個(gè)任務(wù)當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"第四個(gè)任務(wù),當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
//? ? });
#pragma mark -----concurrentQueue__第二種創(chuàng)建方式
//創(chuàng)建globalqueue是蘋果里面的全局隊(duì)列,有四個(gè)優(yōu)先級(jí) 第一個(gè)參數(shù)DISPATCH_QUEUE_PRIORITY_DEFAULT? 隊(duì)列的優(yōu)先級(jí), 第二個(gè)是預(yù)留的參數(shù),為了以后使用,目前還沒使用寫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(@"第一個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第二個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第三任務(wù)當(dāng)前線程%@是否主線稱%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第四個(gè)任務(wù)當(dāng)前 線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第五個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第六個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第七個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第八個(gè)任務(wù)當(dāng)前線程%@是否主線成%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第九個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第十個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
}
//延遲執(zhí)行代碼(dispatch_after 可以再任何隊(duì)列中執(zhí)行,串行 并行,都可以);
- (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));
//創(chuàng)建一個(gè)全局隊(duì)列
dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
//添加到隊(duì)列中
dispatch_after(seconds, queue, ^{
NSLog(@" 我是延遲任務(wù)當(dāng)前任務(wù)線程%@是否是主線程 %d",[NSThread currentThread],[[NSThread currentThread]isMainThread] );
});
}//方法結(jié)尾括號(hào)
//線程組
- (IBAction)groupbutton:(UIButton *)sender {
//線程組:disoatch_group_t主要是吧一些不想關(guān)的任務(wù)就歸為一組
//組里面放的是隊(duì)列
//dispatch_group_async給組里面的隊(duì)列添加任務(wù)
//dispatch_group_notify 作用是監(jiān)聽組里面的任務(wù),等到組里面的任務(wù)全部執(zhí)行完之后,才會(huì)執(zhí)行里面的任務(wù).
//1.創(chuàng)建組
dispatch_group_t group = dispatch_group_create();
//2.創(chuàng)建全局隊(duì)列
dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
//3.往組里添加隊(duì)列
dispatch_group_async(group, queue, ^{
NSLog(@"我是第一個(gè)任務(wù)當(dāng)前線程%@是否是主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_group_notify(group, queue, ^{
NSLog(@"我是最后一個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"這是第二個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是第三個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
}//方法結(jié)尾括號(hào)
//同時(shí)進(jìn)行讀寫
- (IBAction)readandwriteatsametime:(UIButton *)sender {
//數(shù)據(jù)庫的讀取 可以并發(fā)執(zhí)行,通過GCD里面的并行去實(shí)現(xiàn)
//數(shù)據(jù)庫的寫入,只能串發(fā)執(zhí)行,通過GCD里面的串行隊(duì)列去實(shí)現(xiàn);
//但是真正的項(xiàng)目肯定是既有數(shù)據(jù)的讀寫也有數(shù)據(jù)的寫入;如何解決" dispatch _barrier_async 在它之前的任務(wù)可以區(qū)域并發(fā)執(zhí)行,在他之后的任務(wù)也可以并發(fā)執(zhí)行
//創(chuàng)建一個(gè)并行隊(duì)列
dispatch_queue_t queue =dispatch_queue_create("con.concurrent.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"第一任務(wù)當(dāng)前線程%@是否主線成%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第二任務(wù),當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第三任務(wù)當(dāng)前先成%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第四線程當(dāng)前線程%@是否主線成%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第五任務(wù)當(dāng)前任務(wù)%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"我正在讀取數(shù)據(jù)%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第六人物當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第七任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第八任務(wù)呀當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第九任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第十個(gè)任務(wù)當(dāng)前線程%@是否主線程%d",[NSThread currentThread ],[[NSThread currentThread]isMainThread]);
});
}
//多次執(zhí)行
- (IBAction)moretimes:(UIButton *)sender {
NSArray *array =@[@"1",@"2",@"3"];
//同城和數(shù)組配合使用
dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
/*
第一個(gè)參數(shù) 次數(shù)
第二個(gè)參數(shù) 隊(duì)列
第三個(gè)參數(shù) 任務(wù)
*/
//index:記錄當(dāng)前執(zhí)行的第幾次? ,是小于隨機(jī)次數(shù)的
dispatch_apply(3, queue, ^(size_t index ) {
NSLog(@"%@",array[index]);
});
}
//async和sync的區(qū)別
- (IBAction)syncandasyncdiffrent:(UIButton *)sender {
//async不等block體執(zhí)行完畢就去執(zhí)行下面的代碼
//sync 會(huì)等block體執(zhí)行完畢之后才會(huì)執(zhí)行block;
dispatch_queue_t queue=dispatch_get_global_queue(0, 0);
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第一個(gè)任務(wù)");
//? ? });
//? ? NSLog(@"呵呵");
//? ? dispatch_async(queue, ^{
//? ? ? ? NSLog(@"這是第二個(gè)任務(wù)");
//? ? });
//? ? NSLog(@"哦");
dispatch_sync(queue, ^{
NSLog(@"第一個(gè)任務(wù)");
});
NSLog(@"heh");
dispatch_sync(queue, ^{
NSLog(@"第二個(gè)任務(wù)");
});
NSLog(@"o");
}//
//gcd調(diào)用函數(shù)指針
- (IBAction)functionpointer:(UIButton *)sender {
dispatch_queue_t queue=dispatch_get_global_queue(0, 0);
/*
第二個(gè)參數(shù)<#void *context#>函數(shù)參數(shù)的內(nèi)容
第三個(gè)參數(shù)<#dispatch_function_t work#> 函數(shù)(函數(shù)的返回值為void 參數(shù)類型必須為void)
*/
dispatch_async_f(queue, @"hehe", function);
}//
void function(void *context){
NSLog(@"%@",context);
printf("o");
}