多線程淺談之--NSThread以及同步線程鎖

最近兩年多一直在忙著做項(xiàng)目精绎,忽略了很多項(xiàng)目中常用的東西,這段時(shí)間得閑難得把一些東西總結(jié)一下畅涂,也是為了方便自己今后查看宛琅,這篇來談?wù)勅N多線程之一 NSThread雖然不是最常用的但了解了解終歸是好的

NSThread作為三種多線程之一,他是最輕量級(jí)的蒋腮,線程的聲明的生命周期都需要自己手動(dòng)管理淘捡,他的創(chuàng)建方法有三種第一種動(dòng)態(tài)創(chuàng)建

/**
     *  NSThread三種直接間接創(chuàng)建方法
     *  第一種靜態(tài)動(dòng)態(tài)創(chuàng)建方法
     *  selector最多只能接收一個(gè)參數(shù)
     */
    NSThread *thread_1 = [[NSThread alloc] initWithTarget:self selector:@selector(thread1) object:nil];
    thread_1.name = @"thread_1";
    [thread_1 start];

這種方法需要手動(dòng)開啟線程,對(duì)應(yīng)的selector最多只能接收一個(gè)參數(shù)

第二種靜態(tài)創(chuàng)建

/**
     *  第二種靜態(tài)創(chuàng)建方法
     *
     */
    [NSThread detachNewThreadSelector:@selector(thread2) toTarget:self withObject:nil];

這種方法創(chuàng)建即啟動(dòng)

第三種隱式創(chuàng)建

/**
     *  第三種隱式創(chuàng)建方法
     *
     */
    [self performSelectorInBackground:@selector(thread3) withObject:nil];

這種方式還有很多方法稍后一一說明
多線程說白了就是為了讓我們的程序變的不是那么臃腫不卡頓而生池摧,為了替主線程分擔(dān)任務(wù)而存在焦除,當(dāng)我們不管什么操作都放在主線程中進(jìn)行的時(shí)候你會(huì)發(fā)現(xiàn)你的程序恍如一個(gè)遲暮老人一樣遲鈍

NSThread有很多方法 我這里把常用的一一列出

//打印出當(dāng)前線程
    NSLog(@"thread1 --- %@",[NSThread currentThread]);
    //判斷當(dāng)前是否在多線程
    NSLog(@"thread1 --- %d",[NSThread isMultiThreaded]);
    //判斷當(dāng)前是否在主線程
    NSLog(@"thread1 --- %d",[NSThread isMainThread]);
    //讓當(dāng)前線程睡眠幾秒
    [NSThread sleepForTimeInterval:3.];
//讓當(dāng)前線程沉睡到指定時(shí)間
    NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
    [NSThread sleepUntilDate:date];

剛才說了隱式創(chuàng)建的時(shí)候他對(duì)應(yīng)的有多種方法,來看看有哪些

//回到主線程 執(zhí)行UI操作
    [self performSelectorOnMainThread:@selector(doSomeThing) withObject:nil waitUntilDone:YES];

這個(gè)方法很常用作彤,因?yàn)槲覀円话阍谧泳€程中進(jìn)行數(shù)據(jù)請(qǐng)求處理等等膘魄,處理完之后都要更新界面的,這個(gè)操作就需要回到主線程中去操作了

//在指定線程中進(jìn)行某操作
    [self performSelector:@selector(doSomeThing) onThread:thread_1 withObject:nil waitUntilDone:YES];

這個(gè)方法是當(dāng)我們需要將某個(gè)操作添加到某個(gè)線程中進(jìn)行的時(shí)候拿來用的竭讳。
NSThread掌握這些最常用基本就夠用了
下面來討論一下線程鎖的一些東西创葡,我們用到多線程,那有關(guān)線程安全的問題就不能不考慮了绢慢,就比如一個(gè)很經(jīng)典的例子灿渴,售票系統(tǒng),有多個(gè)窗口同時(shí)售票這就是一個(gè)多線程胰舆,他們同時(shí)訪問票務(wù)系統(tǒng)各自獨(dú)立骚露,這就導(dǎo)致了資源爭奪的現(xiàn)象,可能A窗口在訪問一塊資源的時(shí)候缚窿,B窗口也在訪問同一塊資源棘幸,這就出現(xiàn)了這塊資源到底給誰的問題,所以我們需要在A訪問的時(shí)候把資源加鎖滨攻,B只有等待A訪問完了才能訪問
關(guān)于線程鎖我這里說最常用的三個(gè)
@synchronized(self) {}
NSLock
NSCondition
看到第一個(gè)是不是感覺很熟悉我們?cè)诙x屬性的時(shí)候?qū)傩杂袀€(gè)修飾符叫atomic也叫原子性 加了這個(gè)屬性就相當(dāng)于把屬性的setter方法里添加了@synchronized(self) {}來保證安全够话,其實(shí)嚴(yán)格上講他并不是安全的蓝翰,這里隨便說一種

當(dāng)線程A光绕,在setter方法里給屬性設(shè)置值得時(shí)候,此時(shí)B線程在讀屬性的值畜份,因?yàn)閟etter和getter方法是沒有聯(lián)系的诞帐,這時(shí),A在執(zhí)行到加鎖爆雹,只是還沒有設(shè)置值停蕉,然而B線程已經(jīng)讀取走了愕鼓,本來是想讀取A設(shè)置之后的值,卻讀取了設(shè)置之前的值慧起,也就線程不安全了菇晃。

但是如果上面的AB線程都使用了同一把鎖,對(duì)相應(yīng)代碼進(jìn)行加鎖蚓挤,所以鎖內(nèi)的代碼是線程安全的磺送。所謂使用同一把鎖就是@synchronized() {}()中的對(duì)象是同一個(gè)

在這三種加鎖方法中這一種是效率性能最低的

再來看第二個(gè)NSLock

//第二種
        NSLock *lock = [[NSLock alloc] init];
        [lock lock];
        n = arc4random()%100;
        NSLog(@"%ld",(long)n);
        [lock unlock];

這里加鎖的部分是lock塊里面的部分,這里可以防止不同的線程同時(shí)走這個(gè)方法的時(shí)候?qū)賦值出現(xiàn)沖突灿意,在線程A賦值的時(shí)候估灿,線程B也緊隨其后,原本外界需要的是A賦的值可事與愿違拿到了B賦的值缤剧,所以加鎖可以很有效的杜絕這種事情的發(fā)生A執(zhí)行的時(shí)候加上鎖B只能在外面等著A執(zhí)行完

第三種NSCondition

//第三種
        NSCondition *condition = [[NSCondition alloc] init];
        [condition lock];
        n = arc4random()%100;
        NSLog(@"%ld",(long)n);
        [condition unlock];

他也叫條件鎖這個(gè)用起來稍微麻煩點(diǎn)馅袁,可以直接用上面的方法像NSLock一樣用 也可以像下面一樣 判斷是否達(dá)到加鎖條件之后再加鎖

//第三種
        NSConditionLock *conditionLock = [[NSConditionLock alloc] initWithCondition:1];
        BOOL canLock = [conditionLock tryLockWhenCondition:1];
        if (canLock) {
            n = arc4random()%100;
            NSLog(@"%ld",(long)n);
            [conditionLock unlock];
        }

數(shù)字1就是他的判斷條件,在外界可以定義幾個(gè)宏荒辕,來作為判斷條件汗销,這里就不贅述了

這三種加鎖方法如果不考慮性能的話第一種是不錯(cuò)的選擇,如果考慮性能的話第二第三都可以兄纺,不過他們都不是性能最好的
還有一些別的加鎖方法不過不常用大溜,掌握這三個(gè)就已經(jīng)夠用了.

這些只是本人的一些見解有不對(duì)的地方歡迎指出,作者也是個(gè)奮斗在前線的coder估脆,記錄這些也是想加深自己對(duì)此的理解

下一篇來探究三種多線程中的下一種

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钦奋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疙赠,更是在濱河造成了極大的恐慌付材,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圃阳,死亡現(xiàn)場(chǎng)離奇詭異厌衔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)捍岳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門富寿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锣夹,你說我怎么就攤上這事页徐。” “怎么了银萍?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵变勇,是天一觀的道長。 經(jīng)常有香客問我贴唇,道長搀绣,這世上最難降的妖魔是什么飞袋? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮链患,結(jié)果婚禮上巧鸭,老公的妹妹穿的比我還像新娘。我一直安慰自己麻捻,他們只是感情好蹄皱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著芯肤,像睡著了一般巷折。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崖咨,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天锻拘,我揣著相機(jī)與錄音,去河邊找鬼击蹲。 笑死署拟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的歌豺。 我是一名探鬼主播推穷,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼类咧!你這毒婦竟也來了馒铃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤痕惋,失蹤者是張志新(化名)和其女友劉穎区宇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體值戳,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡议谷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了堕虹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卧晓。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赴捞,靈堂內(nèi)的尸體忽然破棺而出逼裆,到底是詐尸還是另有隱情,我是刑警寧澤螟炫,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布波附,位于F島的核電站艺晴,受9級(jí)特大地震影響昼钻,放射性物質(zhì)發(fā)生泄漏掸屡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一然评、第九天 我趴在偏房一處隱蔽的房頂上張望仅财。 院中可真熱鬧,春花似錦碗淌、人聲如沸盏求。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碎罚。三九已至,卻和暖如春纳像,著一層夾襖步出監(jiān)牢的瞬間荆烈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工竟趾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留憔购,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓岔帽,卻偏偏與公主長得像玫鸟,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子犀勒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • 原文地址 http://www.cnblogs.com/kenshincui/p/3983982.html 大家都...
    怎樣m閱讀 1,272評(píng)論 0 1
  • Object C中創(chuàng)建線程的方法是什么屎飘?如果在主線程中執(zhí)行代碼,方法是什么贾费?如果想延時(shí)執(zhí)行代碼枚碗、方法又是什么? 1...
    AlanGe閱讀 1,746評(píng)論 0 17
  • 目錄: (一)線程與進(jìn)程之間的區(qū)別 (二)為什么需要學(xué)習(xí)多線程 (三)多線程任務(wù)執(zhí)行方式 (四)多線程執(zhí)行的...
    KingLionsFrank閱讀 784評(píng)論 6 6
  • 真的铸本,有時(shí)候或許時(shí)間是最好的思想傳遞吧肮雨,我也漸漸懂得時(shí)間所教會(huì)人的許多...... 時(shí)隔七年,難得曾經(jīng)的小...
    蕭蕭_4358閱讀 394評(píng)論 0 0
  • 前言:我們“遠(yuǎn)行”前你最后一篇寫了一首《感懷》箱玷,看到時(shí)我當(dāng)時(shí)在車站送父母回老家怨规,就在評(píng)論區(qū)說了我的想法,今天我重新...
    何時(shí)再出發(fā)閱讀 173評(píng)論 3 1