多線程(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,^{

//

//? ? });

//線程互斥

//創(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");

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容

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